2024-09-02

Redis的哨兵模式是一种监控Redis主服务器和其副本的系统,当主服务器宕机时,哨兵会自动将其中一个副本升级为新的主服务器。

以下是一个基本的哨兵配置文件示例:




# sentinel.conf
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

解释:

  • sentinel monitor mymaster: 这行指定了哨兵监控的主节点名称为mymaster,后面跟着主节点的IP和端口,以及最少需要有多少个哨兵同意认为主节点宕机才会进行故障转移。
  • sentinel down-after-milliseconds: 如果一个主服务器在指定的毫秒数内没有响应,则认为它是主观下线。
  • sentinel parallel-syncs: 在故障转移期间,可以有几个从服务器同时进行同步。
  • sentinel failover-timeout: 故障转移超时时间。

启动哨兵的命令通常如下:




redis-sentinel /path/to/sentinel.conf

在实际部署时,你需要根据你的网络环境和Redis版本调整哨兵的配置。

2024-09-02

Redis是一个开源的使用C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

Redis基础知识:

Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

Redis支持数据的备份,即master-slave模式的数据备份。

Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

Redis五大数据类型:

  1. String:字符串是最基本的数据类型,可以理解为与Memcached一模一样的类型。
  2. Hash:哈希,类似于Map。
  3. List:列表,类似于LinkedList,支持重复元素。
  4. Set:集合,类似于Set,不支持重复元素。
  5. Sorted Set:有序集合,不支持重复元素,每个元素都会关联一个double类型的分数,通过分数的排序来组织元素。

Redis的三种特殊数据类型:

  1. Bitmap:位图,可以对位进行操作。
  2. HyperLogLog:用于计算集合的基数,适用于大数据量的计算。
  3. Geo:地理位置,可以用来存储地理位置信息,并进行位置的计算。

Redis的事务:

Redis的事务会将多个命令在执行的时候看做一个整体,要么全部成功,要么全部失败。

Redis的事务没有隔离级别的概念,也就是说在事务执行的过程中可能会被其他的命令插入。

Redis的事务不支持回滚操作。

以上是Redis的基本概念,具体的使用方法和命令可以参考Redis官方文档。

2024-09-02

缓存击穿、缓存穿透、缓存雪崩是指在使用Redis作为缓存时可能遇到的三个问题:

  1. 缓存击穿:指缓存中的一个Key在大量请求同时进来时,缓存失效,导致大量请求直接打到数据库上。

解决方法:

  • 设置热点数据永不过期或者较长的过期时间。
  • 加互斥锁,只有一个线程去数据库加载数据并更新缓存,其他线程等待。
  • 使用锁或者队列控制数据库的访问。
  1. 缓存穿透:指非法用户不断发送带有大量不存在的Key的请求,如果这些Key没有被缓存,则请求会穿透到数据库,给数据库带来压力。

解决方法:

  • 使用布隆过滤器,先检查Key是否存在。
  • 为Key加上一个随机前缀或者后缀,减少攻击的可能性。
  • 设置Key的默认值,缓存一个空值或者错误信息,避免击穿。
  1. 缓存雪崩:指在某一时刻,缓存服务器宕机或者大量缓存集中在某一时刻失效,导致大量请求直接打到数据库上。

解决方法:

  • 保证Redis服务的高可用性。
  • 使用Redis集群。
  • 设置热点数据永不过期或者较长的过期时间。
  • 在缓存失效后,通过加锁或队列控制数据库的访问,防止大量请求同时打到数据库上。
2024-09-02

天猫商城项目基于前后端分离的架构,后端使用SpringBoot和JPA,前端使用Vue.js和Element UI。以下是一个简化的后端SpringBoot应用的代码示例:




// 引入SpringBoot相关依赖
@SpringBootApplication
@EnableJpaRepositories
@EntityScan
public class TmallApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(TmallApplication.class, args);
    }
}
 
// 实体类示例
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Double price;
    // 省略其他字段、getter和setter方法
}
 
// Repository接口示例
public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findByNameContaining(String name);
}
 
// 服务层示例
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;
 
    public List<Product> searchProductByName(String name) {
        return productRepository.findByNameContaining(name);
    }
}
 
// 控制层示例
@RestController
@RequestMapping("/api/v1/product")
public class ProductController {
    @Autowired
    private ProductService productService;
 
    @GetMapping("/search")
    public ResponseEntity<?> searchProduct(@RequestParam String name) {
        List<Product> products = productService.searchProductByName(name);
        return ResponseEntity.ok(products);
    }
}

前端Vue.js的代码示例:




// 引入axios进行HTTP请求
import axios from 'axios';
 
export default {
    data() {
        return {
            productList: [],
            searchKey: ''
        };
    },
    methods: {
        searchProduct() {
            axios.get('/api/v1/product/search?name=' + this.searchKey)
                .then(response => {
                    this.productList = response.data;
                })
                .catch(error => {
                    console.error('Search product error:', error);
                });
        }
    }
};

以上代码提供了一个简单的后端SpringBoot应用和一个简单的前端Vue.js应用框架,展示了如何进行RESTful API的设计和实现。在实际项目中,还需要考虑更多安全性、认证、权限管理等方面的需求。

2024-09-02

Redis是一个开源的使用C语言编写的、支持网络交互的、可基于内存也可持久化的日志型、Key-Value数据库,并提供多种语言的API。

Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

Redis的9种数据结构如下:

  1. String
  2. List
  3. Set
  4. Sorted Set
  5. Hash
  6. Bitmap
  7. HyperLogLog
  8. Geo
  9. Stream

下面我们来详细解析一下这9种数据结构:

  1. String

String是Redis最基本的类型,你可以理解成与Memcached一模一个的类型,它是二进制安全的,可以存储任何数据,包括图片等。

  1. List

List是一个双向链表,可以从两端进行push和pop操作。

  1. Set

Set是一个无序的集合,集合中的元素都是唯一的。

  1. Sorted Set

Sorted Set是一个有序的集合,每个元素都会关联一个浮点数的分数,通过这个分数来进行排序。

  1. Hash

Hash是一个键值对集合,是一个string类型的field和value的映射表,适合存储对象。

  1. Bitmap

Bitmap是一个非常大的位数组,可以用来做位级别的操作,如计数、状态变更等。

  1. HyperLogLog

HyperLogLog是用来做基数统计的算法,适用于大数据量的基数统计,它只需要很少的内存。

  1. Geo

Geo是用来处理地理位置信息的,可以进行地理位置的查询,比如:距离查询,经纬度的查询等。

  1. Stream

Stream是一个新的数据类型,它是按照时间顺序存储消息的,可以用来实现类似于Kafka的功能,可以用来实现消息队列、事件流等功能。

以上就是Redis的9种数据结构,每种数据结构都有自己的特点和应用场景,可以根据实际需求选择合适的数据结构。

2024-09-02

Redis是一个开源的,基于内存的数据结构存储系统,可以用作数据库、缓存和消息传递队列。

以下是一些Redis的基本操作和示例代码:

  1. 连接Redis服务器



import redis
 
r = redis.Redis(host='localhost', port=6379, db=0)
  1. 设置键值对



r.set('foo', 'bar')
  1. 获取键值



r.get('foo')
  1. 删除键值对



r.delete('foo')
  1. 设置带有过期时间的键值对



r.setex('hello', 10, 'world')  # 键'hello'在10秒后过期
  1. 批量设置键值对



r.mset({'key1': 'value1', 'key2': 'value2'})
  1. 批量获取键值对



r.mget(['key1', 'key2'])
  1. 使用哈希表



r.hset('hash_key', 'field1', 'value1')
r.hget('hash_key', 'field1')
  1. 列表操作



r.rpush('list_key', 'value1')
r.lpush('list_key', 'value2')
r.lrange('list_key', 0, -1)  # 获取列表所有元素
  1. 集合操作



r.sadd('set_key', 'member1')
r.smembers('set_key')  # 获取集合所有成员
  1. 有序集合操作



r.zadd('zset_key', {'member1': 1})
r.zrange('zset_key', 0, -1)  # 获取有序集合所有成员
  1. 通过Lua脚本执行多个命令



script = """
local num = redis.call('incr', KEYS[1])
if num == 1 then
    redis.call('expire', KEYS[1], ARGV[1])
end
return num
"""
r.eval(script, 1, 'mykey', 10)
  1. 监听键空间通知



# 首先在Redis配置文件中开启键空间通知
r.psubscribe(**{'__keyevent@0__:set': lambda *args: print(args)})

以上是Redis操作的基本示例,Redis还有很多高级特性和使用场景,如分布式锁、队列等,需要根据具体需求进行使用。

2024-09-02



import redis
import uuid
 
# 假设这是商品信息
product_id = "123"
product_price = 1000
 
# 连接Redis
r = redis.Redis(host='localhost', port=6379, db=0)
 
# 秒杀业务实现
def seckill(product_id, product_price):
    # 生成唯一订单ID
    order_id = str(uuid.uuid4())
 
    # 检查库存,使用Redis的原子操作
    stock_key = f"product:{product_id}:stock"
    with r.pipeline() as pipe:
        pipe.watch(stock_key)
        stock = r.get(stock_key)
        if stock and int(stock) > 0:
            pipe.multi()
            pipe.decr(stock_key)
            pipe.execute()
            # 扣款成功,创建订单等
            create_order(order_id, product_id, product_price)
        else:
            print("库存不足")
 
# 创建订单
def create_order(order_id, product_id, product_price):
    # 这里可以实现订单的创建逻辑,例如保存到数据库等
    print(f"订单创建成功: 订单ID: {order_id}, 商品ID: {product_id}, 商品价格: {product_price}")
 
# 调用秒杀业务
seckill(product_id, product_price)

这段代码展示了如何使用Redis实现一个简单的秒杀业务。其中,seckill函数负责实现秒杀逻辑,包括生成唯一订单ID、检查库存、扣款以及创建订单。使用Redis的原子操作DECR来实现库存的扣减,并通过watch命令来避免超卖问题。这是一个简化的例子,实际应用中需要考虑更多的安全性、可用性和性能因素。

2024-09-02

Redis Stack是指Redis的集群模式,它是Redis提供的一种方式,可以通过多个Redis节点组成一个集群来提供更高的可用性和数据存储能力。

以下是在Linux环境下使用Redis Stack的简要安装和配置步骤:

  1. 安装Redis



sudo apt-get update
sudo apt-get install redis-server
  1. 修改Redis配置以启用集群模式

    编辑Redis配置文件 /etc/redis/redis.conf,找到下面的配置项并进行修改:




cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
  1. 复制Redis服务并创建多个实例



sudo cp /etc/init/redis-server.conf /etc/init/redis-server-6380.conf
sudo cp /etc/init/redis-server.conf /etc/init/redis-server-6381.conf

修改这些新的配置文件,将其中的6379改为新的端口号,例如63806381

  1. 启动Redis实例



sudo service redis-server start
sudo service redis-server-6380 start
sudo service redis-server-6381 start
  1. 使用redis-cli创建集群



redis-cli --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 --cluster-replicas 1

这里--cluster-replicas 1表示每个主节点都有一个副本。

以上步骤可以用于快速部署一个小型的Redis集群。对于生产环境,你可能需要考虑更多的配置细节,比如网络配置、负载均衡器、持久化选项等。

2024-09-02



@RestController
public class LoginController {
 
    @Autowired
    private StringRedisTemplate redisTemplate;
 
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody UserLoginIn userLoginIn){
        // 假设验证用户是通过的
        boolean isVerify = UserVerify.verify(userLoginIn.getUsername(), userLoginIn.getPassword());
        if (!isVerify){
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("登录失败");
        }
        // 生成Token
        String token = JwtUtils.generateToken(userLoginIn.getUsername());
        // 存储Token到Redis,假设有效期为1天
        redisTemplate.opsForValue().set(token, token, 1, TimeUnit.DAYS);
        return ResponseEntity.ok(token);
    }
 
    @GetMapping("/validate")
    public ResponseEntity<?> validateToken(@RequestHeader("Authorization") String token){
        // 从Redis获取Token进行比对
        String redisToken = redisTemplate.opsForValue().get(token);
        if (redisToken == null || !redisToken.equals(token)){
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Token失效或未认证");
        }
        return ResponseEntity.ok("Token有效");
    }
}
 
// 假设的UserLoginIn类
class UserLoginIn {
    private String username;
    private String password;
    // getter和setter略
}
 
// 假设的UserVerify类
class UserVerify {
    static boolean verify(String username, String password){
        // 假设验证逻辑,返回验证结果
        return "user".equals(username) && "pass".equals(password);
    }
}
 
// 假设的JwtUtils工具类
class JwtUtils {
    static String generateToken(String username){
        // 假设的JWT生成逻辑,返回生成的Token
        return "Bearer ey123...";
    }
}

这个代码示例展示了如何在Spring Boot项目中使用JWT和Redis来完成登录流程和Token验证。在login接口中,用户提交用户名和密码进行登录,成功后生成JWT Token并将其存储到Redis中。在validateToken接口中,通过从Redis获取Token与请求中的Token进行比对,来验证Token的有效性。这个示例假设了一些工具类和方法的实现,实际应用中需要根据项目具体情况进行调整。

2024-09-02

Redis哨兵和集群是Redis高可用性和扩展性的两个解决方案。

  1. 哨兵(Sentinel)

哨兵是Redis高可用性的解决方案,由一个或多个哨兵实例组成的系统可以监控主服务器和其从服务器,并在主服务器下线时自动进行故障转移。

以下是一个基本的哨兵配置文件示例:




sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

这个配置文件指定了哨兵监控主服务器mymaster,当这个主服务器30秒无法通信时,哨兵将其认定为下线。并且,在故障转移期间,最多只能有1个从服务器同步。

  1. 集群(Cluster)

Redis集群是一种部署方式,它通过多个Redis节点共享数据来提供更高的可用性和更大的数据量。

以下是一个基本的集群配置文件示例:




port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

这个配置文件启用了集群模式,并指定了集群配置文件和节点超时时间。

在集群环境中,客户端可以连接任何一个节点来进行读写操作,并且当数据跨节点时,集群会自动处理数据分片和同步。

注意:实际部署时,哨兵和集群通常结合使用,以提供更完整的Redis高可用性和数据分布解决方案。