2024-09-01

在使用Redis实现分布式锁时,确保一致性需要遵循以下步骤:

  1. 获取锁:使用SETNX命令尝试获取锁,只有当锁未被占用时才能成功。
  2. 设置超时时间:使用EXPIRE命令为锁设置一个超时时间,以防止死锁。
  3. 检查锁的状态:在释放锁之前,确保释放的是自己占用的锁,可以通过比较值或者使用GET和对比命令来实现。
  4. 释放锁:释放锁时,确保锁是由当前客户端占用,然后使用DEL命令释放锁。

以下是一个简单的Python示例,使用redis-py库实现分布式锁:




import redis
import time
import uuid
 
def acquire_lock(conn, lock_name, acquire_timeout=10, lock_timeout=10):
    identifier = str(uuid.uuid4())
    end = time.time() + acquire_timeout
 
    while time.time() < end:
        if conn.setnx(lock_name, identifier):
            conn.expire(lock_name, lock_timeout)
            return identifier
        time.sleep(0.001)
 
    return False
 
def release_lock(conn, lock_name, identifier):
    pipe = conn.pipeline(True)
    while True:
        try:
            pipe.watch(lock_name)
            if pipe.get(lock_name) == identifier:
                pipe.multi()
                pipe.delete(lock_name)
                pipe.execute()
                return True
            pipe.unwatch()
            break
        except redis.exceptions.WatchError:
            pass
    return False
 
# 使用示例
client = redis.StrictRedis(host='localhost', port=6379, db=0)
lock_name = "my_lock"
lock_id = acquire_lock(client, lock_name)
if lock_id:
    try:
        # 处理任务...
        pass
    finally:
        if release_lock(client, lock_name, lock_id):
            print("Lock released successfully")
        else:
            print("Unable to release lock")
else:
    print("Unable to acquire lock")

在实际应用中,为了确保在发生故障时锁能够被正确释放,可以使用Redlock算法或者Redlock库来实现更健壮的一致性保证。

2024-09-01

在Spring Data Redis中,RedisTemplateopsForValue().setIfAbsent()方法用于尝试将一个key-value对存入Redis。如果这个key不存在,那么就会设置这个key-value对,并返回true表示设置成功。如果这个key已经存在,那么不会覆盖原来的value,也不会改变原来的expire time,方法会返回false表示设置失败。

如果你遇到springboot redisTemplate.opsForValue().setIfAbsent()返回null的情况,那么很可能是因为你没有正确配置RedisTemplate或者你的方法没有被Spring管理造成的。

解决方法:

  1. 确保你的RedisTemplate已经被Spring容器正确管理,并且已经设置了合适的序列化器。
  2. 确保你的方法是被Spring管理的,如果是在Controller中调用,确保Controller本身是被Spring容器管理的。
  3. 如果你在使用注解配置,确保你的配置类被@Configuration注解,并且你的RedisTemplate@Bean方法定义。
  4. 确保你没有配置多个RedisTemplate实例,这会导致Spring不知道使用哪一个。

示例代码:




@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        // 配置序列化器,例如使用Jackson2JsonRedisSerializer
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setDefaultSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

然后在你的Service中注入RedisTemplate




@Service
public class YourService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
 
    public boolean setIfAbsent(String key, Object value) {
        return redisTemplate.opsForValue().setIfAbsent(key, value);
    }
}

确保你的Service也是被Spring容器管理的,这样RedisTemplate就可以被注入并且可以正常使用了。

2024-09-01

解释:

Redis未授权访问通常意味着Redis服务器没有设置密码保护,任何人都可以通过网络访问这个服务,这在安全性方面是非常不推荐的。未授权访问可能会导致数据泄露、数据修改或其他不当行为。

解决方法:

  1. 设置Redis密码:编辑Redis配置文件(通常是redis.conf),找到# requirepass foobared这行,去掉前面的#并将foobared替换为你自己的密码。然后重启Redis服务。
  2. 使用Redis的AUTH命令:连接到Redis后,使用AUTH yourpassword命令进行认证。
  3. 使用配置管理工具:如果你使用的是像Ansible、SaltStack或者其他配置管理工具,可以通过工具来安全地管理和分发配置文件。
  4. 监控和记录:确保启用了Redis的访问控制列表(ACL),以便监控和记录谁在访问Redis,并对未授权的访问实行警告或阻止。
  5. 定期更新密码:定期更换你的密码以增强安全性。
  6. 使用TLS/SSL:如果可能,配置Redis以使用TLS/SSL加密通讯来进一步提高安全性。

确保在实施任何安全措施之前,你已经备份了你的数据,并且了解如何在出现问题时恢复数据。

2024-09-01

在搭建Redis主从复制架构时,你需要准备至少两个Redis服务实例,一个作为主节点(Master),其余作为从节点(Slave)。以下是基于Linux环境搭建Redis主从复制的步骤和示例配置:

  1. 安装Redis:确保你的系统上安装了Redis。
  2. 配置Master节点:

    • 编辑Master节点的redis.conf文件,设置bind指令为Master的IP地址,并设置port为默认的6379。
    • 确保daemonize设置为yes,以便Redis能作为守护进程运行。
    • 可以选择设置requirepass来设置访问密码。
  3. 配置Slave节点:

    • 编辑Slave节点的redis.conf文件,设置bind指令为Slave的IP地址,并设置port为不同于Master的端口。
    • 设置daemonizeyes
    • 设置slaveof指令为Master节点的IP和端口,如slaveof <master-ip> <master-port>
    • 如果Master设置了访问密码,Slave也应设置masterauth为Master的密码。
  4. 启动Redis服务:

    • 在Master节点上启动Redis服务:redis-server /path/to/redis.conf
    • 在Slave节点上启动Redis服务:redis-server /path/to/redis.conf
  5. 验证主从复制:

    • 连接到Master节点,并检查信息:redis-cli -h <master-ip> -p <master-port>
    • 使用INFO replication命令查看复制信息。
    • 连接到Slave节点,并检查信息:redis-cli -h <slave-ip> -p <slave-port>
    • 使用INFO replication命令查看复制信息。

以下是示例配置:

Master节点的redis.conf




bind 192.168.1.100
port 6379
daemonize yes
requirepass yourmasterpassword

Slave节点的redis.conf




bind 192.168.1.101
port 6379
daemonize yes
slaveof 192.168.1.100 6379
masterauth yourmasterpassword

启动服务后,你可以通过连接到每个节点并执行INFO replication命令来查看复制状态和信息。

2024-09-01

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

Redis 的基础数据结构包括字符串、哈希表、列表、集合、有序集合等。

  1. 字符串(String)

字符串是 Redis 最基本的数据类型。




# 设置键值
redis.set('key', 'value')
# 获取键值
redis.get('key')
  1. 哈希表(Hash)

哈希表用于存储键值对集合。




# 设置哈希表
redis.hset('hash_key', 'field1', 'value1')
# 获取哈希表
redis.hget('hash_key', 'field1')
  1. 列表(List)

列表是简单的字符串列表,可以添加一个元素到列表的头部或尾部。




# 在列表头部添加元素
redis.lpush('list_key', 'value1')
# 在列表尾部添加元素
redis.rpush('list_key', 'value2')
# 获取列表
redis.lrange('list_key', 0, -1)
  1. 集合(Set)

集合是无序的字符串集合。




# 添加元素
redis.sadd('set_key', 'value1')
# 获取集合
redis.smembers('set_key')
  1. 有序集合(Sorted Set)

有序集合是字符串的有序集合。




# 添加元素
redis.zadd('zset_key', {'value1': 1})
# 获取集合
redis.zrange('zset_key', 0, -1)

以上操作均为 Redis 基础操作,在实际应用中,可以结合业务场景进行复杂操作,例如实现缓存系统、消息队列、计数器、分布式锁等。

2024-09-01

一、部署Redis哨兵集群

  1. 安装Redis并启动主服务器



# 安装Redis
sudo apt-install redis-server
 
# 修改Redis配置文件
sudo nano /etc/redis/redis.conf
 
# 确保以下配置项被设置
bind 0.0.0.0
daemonize yes
 
# 启动Redis服务
sudo systemctl start redis-server
  1. 配置两个从服务器

    对于每个从服务器,重复步骤1,并在redis.conf中添加以下配置:




slaveof <master-ip> <master-port>
  1. 安装和配置哨兵

    在每个哨兵上执行以下步骤:




# 安装Redis
sudo apt-install redis-server
 
# 修改Redis配置文件
sudo nano /etc/redis/redis.conf
 
# 确保以下配置项被设置
bind 0.0.0.0
daemonize yes
sentinel monitor mymaster <master-ip> <master-port> 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
 
# 启动哨兵
redis-sentinel /etc/redis/redis.conf

二、知识点总结

  • 哨兵负责监控主服务器和从服务器,并在主服务器宕机时自动进行故障转移。
  • 配置项sentinel monitor mymaster <master-ip> <master-port> 2指定主服务器和最小投票数2。
  • 配置项sentinel down-after-milliseconds mymaster 30000指定判断主服务器宕机的时间。
  • 配置项sentinel parallel-syncs mymaster 1指定一次最多同步的从服务器数。
  • 配置项sentinel failover-timeout mymaster 180000指定故障转移的超时时间。

三、常见问题和解决方案

  1. 如何连接哨兵集群?

    连接哨兵,使用redis-cli命令,指定哨兵的IP和端口,例如:redis-cli -h <sentinel-ip> -p <sentinel-port>

  2. 如何获取当前主服务器信息?

    连接到哨兵后,使用命令SENTINEL get-master-addr-by-name <master-name>

  3. 哨兵集群如何处理故障转移?

    当主服务器宕机,哨兵会选举一个哨兵作为领导者,进行故障转移流程,包括选举新的主服务器和配置其他从服务器指向新主。

  4. 哨兵集群如何处理手动故障转移?

    可以通过SENTINEL failover <master-name>命令手动触发故障转移。

  5. 哨兵集群如何处理配置变更?

    哨兵会监控主服务器和从服务器的配置文件,一旦有变更会自动更新配置。

四、扩展和优化

  • 可以使用哨兵集群来进一步提高可用性,部署多个哨兵实例以提高监控的可靠性和性能。
  • 可以开启Redis的持久化机制,如RDB或AOF,以防止数据丢失。
  • 可以配置主服务器和从服务器的自动重启功能,以便在服务器重启后自动恢复服务。
  • 可以使用自定义的监控脚本来扩展哨兵
2024-09-01

概述

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

特性

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s。
  • 持久化 – 可以将内存中的数据保存在硬盘中,重启时可以再次加载。
  • 多种数据类型 – 支持字符串(String), 列表(List), 集合(Set), 有序集合(Sorted Set) 和 哈希类型(Hash) 等数据类型。
  • 原子性 – 所有操作都是原子性,要么成功要么失败。
  • 支持多种编程语言 – 支持Python, Ruby, Erlang, Tcl等服务器端语言。

应用场景

  • 缓存系统 – 因为Redis能读的速度是110000次/s,写的速度是81000次/s,所以非常适合作为缓存系统。
  • 分布式集群的会话存储 – 比如Java中的Tomcat、Memcached就是使用Redis做会话存储。
  • 计数器/限速器 – 可以使用Redis的INCR, DECR命令实现。
  • 消息队列 – 使用List作为队列,使用Pub/Sub作为发布/订阅。
  • 排行榜/计分板 – 使用Sorted Set。

安装

  • Linux下安装:

    
    
    
    # 下载
    wget http://download.redis.io/releases/redis-5.0.5.tar.gz
    # 解压
    tar xzf redis-5.0.5.tar.gz
    # 编译
    cd redis-5.0.5
    make
    # 测试
    make test
    # 安装
    sudo make install
  • Windows下安装:

    可以通过下载官方提供的Windows版本或使用WSL(Windows Subsystem for Linux)。

客户端

  • 命令行客户端:

    
    
    
    redis-cli
  • 多种编程语言的客户端:

    • Python: redis-py
    • Java: Jedis
    • Node.js: ioredis
    • Ruby: redis-rb
    • C#: StackExchange.Redis

以上是Redis的基本概念、特性和应用场景,以及如何在Linux和Windows上安装Redis及其常用客户端。

2024-09-01

Redis 常见的数据类型及操作方法如下:

  1. 字符串(String)

    • 设置值:SET key value
    • 获取值:GET key
    • 增加数字:INCR keyDECR key
    • 追加值:APPEND key value
  2. 列表(List)

    • 从列表左侧插入:LPUSH key value
    • 从列表右侧插入:RPUSH key value
    • 获取列表:LRANGE key start stop
    • 从列表左侧弹出:LPOP key
    • 从列表右侧弹出:RPOP key
  3. 集合(Set)

    • 添加元素:SADD key member
    • 获取全部元素:SMEMBERS key
    • 删除元素:SREM key member
    • 判断元素是否存在:SISMEMBER key member
  4. 有序集合(Sorted Set)

    • 添加元素:ZADD key score member
    • 获取全部元素:ZRANGE key start stop
    • 删除元素:ZREM key member
    • 按分数范围获取元素:ZRANGEBYSCORE key min max
  5. 哈希(Hash)

    • 设置值:HSET key field value
    • 获取值:HGET key field
    • 获取所有字段和值:HGETALL key
    • 删除字段:HDEL key field
  6. 位图(Bitmap)

    • 设置位:SETBIT key offset value
    • 获取位:GETBIT key offset
    • 统计位为1的数量:BITCOUNT key
  7. HyperLogLog

    • 添加元素:PFADD key element
    • 计算基数:PFCOUNT key
    • 合并多个HyperLogLog:PFMERGE destkey sourcekey [sourcekey ...]
  8. 发布/订阅(Pub/Sub)

    • 订阅频道:SUBSCRIBE channel [channel ...]
    • 发布消息:PUBLISH channel message
  9. 事务(Transaction)

    • 开启事务:MULTI
    • 执行事务:EXEC
    • 放弃事务:DISCARD
  10. 键管理

    • 查看键:KEYS pattern
    • 删除键:DEL key
    • 检查键是否存在:EXISTS key
    • 设置过期时间:EXPIRE key seconds

这些是Redis中最常见的数据类型和操作方法。在实际应用中,可以根据需要选择合适的数据类型和操作命令。

2024-09-01

在Redis中,数据的持久化主要有两种方式:RDB(Redis DataBase)和AOF(Append Only File)。

  1. RDB:定时将内存中的数据快照保存到磁盘的一个压缩二进制文件中。可以配置定时任务来控制快照的频率。



# 在redis.conf中配置
save 900 1      # 900秒内至少1个键被修改则触发保存
save 300 10     # 300秒内至少10个键被修改则触发保存
save 60 10000   # 60秒内至少10000个键被修改则触发保存
 
dbfilename dump.rdb  # RDB文件名
dir /path/to/your/redis/directory  # RDB文件存储目录
  1. AOF:每个写命令都通过append操作保存到文件中。在Redis重启时,通过重放这些命令来恢复数据。



# 在redis.conf中配置
appendonly yes  # 开启AOF
appendfilename "appendonly.aof"  # AOF文件名
dir /path/to/your/redis/directory  # AOF文件存储目录

# AOF文件的更新频率
appendfsync always  # 每次写入都同步,最慢但最安全
appendfsync everysec  # 每秒同步一次,折衷方案
appendfsync no  # 完全依赖操作系统,最快但不安全

在实际操作中,可以根据数据的重要性和性能需求选择合适的持久化方式。如果对数据持久化要求不高,可以只使用RDB;如果对数据安全性要求较高,并且可以接受较长时间的数据丢失,可以只使用AOF;如果需要既保证数据安全性又想要较好的性能,可以同时开启RDB和AOF。

2024-09-01

Redis支持三种集群模式:主从模式、哨兵模式和Cluster模式。

  1. 主从模式(Master-Slave Mode)

主从模式是最简单的Redis集群模式。在这种模式下,有一个主节点和一个或多个从节点,主节点用于处理写操作,从节点用于处理读操作。数据是以快照的方式从主节点同步到从节点。




# 配置主节点
redis-server /etc/redis/redis.conf

# 配置从节点
redis-server /etc/redis/redis.conf --slaveof 127.0.0.1 6379
  1. 哨兵模式(Sentinel Mode)

哨兵模式是主从模式的升级版。它通过哨兵进程监控主节点和从节点,并在主节点出现故障时自动进行故障转移。




# 启动哨兵进程
redis-sentinel /etc/redis/sentinel.conf
  1. Cluster模式(Cluster Mode)

Cluster模式是最复杂的Redis集群模式,它通过分片(sharding)机制实现数据的分布式存储。在Cluster模式下,数据是以集群内部的一个个节点存储的,每个节点都可以处理读写操作。




# 配置Cluster环境
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 --cluster-replicas 1

以上是三种Redis集群模式的简要说明和配置示例。在实际应用中,你需要根据具体需求选择合适的集群模式,并进行相应的配置。