• [技术干货] Redis基础使用入门指南
    Redis(Remote Dictionary Server)是一个开源的、基于内存的键值对存储数据库,以其高性能、丰富的数据结构和灵活的应用场景而广受欢迎。它不仅可以用作缓存系统,还能作为数据库、消息队列等多种用途。本文将带你快速入门Redis的基础使用。一、Redis简介Redis由Salvatore Sanfilippo开发,采用ANSI C语言编写,支持多种操作系统(如Linux、macOS、Windows等)。其核心特点包括:基于内存存储:读写速度极快,适合高并发场景。持久化支持:支持RDB(快照)和AOF(日志)两种持久化机制,确保数据安全。丰富的数据类型:支持字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等。原子性操作:所有操作都是原子的,保证线程安全。主从复制与高可用:支持主从架构、哨兵模式和集群部署。二、安装与启动1. 安装Redis(以Linux为例)# Ubuntu/Debiansudo apt updatesudo apt install redis-server# CentOS/RHELsudo yum install epel-releasesudo yum install redis2. 启动Redis服务# 启动服务sudo systemctl start redis-server# 设置开机自启sudo systemctl enable redis-server# 检查状态sudo systemctl status redis-server3. 连接Redis# 使用Redis自带的命令行客户端redis-cli连接成功后,可输入 ping 测试:127.0.0.1:6379> pingPONG三、基本数据类型与操作1. 字符串(String)最简单的键值对,值可以是字符串或数字。# 设置键值SET name "Alice"# 获取值GET name# 输出: "Alice"# 自增INCR counter # 若counter不存在,则设为0再+1INCRBY counter 5# 设置过期时间(秒)EXPIRE name 602. 哈希(Hash)适合存储对象,如用户信息。# 设置哈希字段HSET user:1001 name "Bob" age 25 email "bob@example.com"# 获取单个字段HGET user:1001 name# 输出: "Bob"# 获取所有字段HGETALL user:10013. 列表(List)有序的字符串列表,支持在头部或尾部插入。# 向列表左侧插入LPUSH tasks "task1" "task2"# 向右侧插入RPUSH tasks "task3"# 查看列表内容LRANGE tasks 0 -1# 输出: ["task2", "task1", "task3"]# 弹出左侧元素LPOP tasks4. 集合(Set)无序且唯一的字符串集合。# 添加元素SADD tags "redis" "database" "cache"# 查看所有元素SMEMBERS tags# 判断是否包含SISMEMBER tags "redis"# 输出: 1(存在)5. 有序集合(Sorted Set)带权重的集合,按分数排序。# 添加成员(分数在前)ZADD leaderboard 100 "Alice" 90 "Bob" 85 "Charlie"# 获取排名(从高到低)ZREVRANGE leaderboard 0 -1 WITHSCORES# 输出: Alice, 100, Bob, 90, Charlie, 85
  • [技术干货] 【浅谈】以 Redis Cluster 为例,它是如何在 CAP 中做权衡的?其数据分片和故障转移机制分别体现了对哪些特性的优先保障?
    核心结论:Redis Cluster 的 CAP 权衡Redis Cluster 优先保障 CP,即在网络分区(Partition)发生时,它会优先保障一致性(C) 和分区容错性(P),而牺牲可用性(A)。这意味着,当发生脑裂(网络分区)时,Redis Cluster 会确保在多数派(Master)主节点所在的分区继续提供服务,而少数派分区中的节点会拒绝写入(甚至部分读取),从而避免数据不一致。这期间,连接到少数派分区的客户端可能会收到错误,从而体验到服务不可用。1. 数据分片机制与 CAP 保障Redis Cluster 采用分片(Sharding) 的方式来管理数据,具体是通过哈希槽(Hash Slot)实现的。机制:整个集群有 16384 个哈希槽。每个键通过 CRC16 校验后,对 16384 取模,被分配到一个唯一的槽中。集群将这些槽分配给各个主节点(Master)。每个主节点负责一部分槽位。客户端可以请求任意节点,如果该键不在当前节点,节点会返回 MOVED 错误并告知正确节点,由客户端进行重定向。体现的 CAP 特性:一致性 (C):数据分片机制是保障强一致性的基础。它通过将数据分散,使得每个主节点只需要维护自己负责的那部分数据的一致性。在数据读写时,操作被限定在特定的主节点及其副本上,这为实现强一致性协议(如 Redis Cluster 的异步复制)创造了条件。分区容错性 (P):分片本身就是分区容错性的体现。数据被分布到多个节点上,单个节点或部分节点的故障不会导致整个集群数据的完全丢失。系统被设计为即使在部分节点不可用时,其他节点仍然可以继续服务。可用性 (A):分片本身提升了整体的可用性,因为一个分片的故障不影响其他分片。但是,在 CAP 的语境下,当发生网络分区时,分片机制会与故障转移机制协同工作,最终做出牺牲部分分片可用性以保障一致性的选择。小结:数据分片机制主要服务于 P(将数据分散以容忍部分故障)和 C(为局部一致性管理打下基础)。2. 故障转移机制与 CAP 保障故障转移是 Redis Cluster 在面临节点故障或网络分区时,维持 CP 特性的核心。机制:心跳与故障探测:所有节点通过 Gossip 协议互相通信。每个主节点会定期向其他主节点发送 PING 消息。如果一个主节点在超过 cluster-node-timeout 时间内未收到另一个主节点的 PONG 回复,它会将其标记为“疑似下线”(PFAIL)。如果集群中大多数主节点都认为某个主节点下线,则将其标记为“已下线”(FAIL),并广播这一消息。从节点晋升:当一个主节点被确认为 FAIL 状态后,其下的一个从节点会发起竞选。这个从节点必须能够连接到集群中的大多数主节点,才能获得投票并晋升为新的主节点。配置纪元(Configuration Epoch):这是一个单调递增的版本号,用于在出现多个冲突的决策(比如脑裂后恢复时出现两个主节点)时,判定哪个决策是最新的,从而解决冲突,保证集群最终只有一个配置胜出。体现的 CAP 特性:一致性 (C):这是最关键的部分。故障转移机制通过 “大多数(Majority)”原则 来保障一致性。一个从节点必须得到大多数主节点的同意才能成为新的主节点。这意味着,在网络分区中,只有拥有大多数主节点的那个分区(多数派分区)才能成功完成故障转移。少数派分区中的节点,因为无法连接到大多数主节点,其从节点无法成功晋升。因此,少数派分区中的原主节点(即使它还在运行)会被集群其他部分视为已下线,它自己也会因为无法完成写入确认而进入错误状态。这就防止了在少数派分区中出现“脏写”,从而避免了脑裂导致的数据不一致。分区容错性 (P):整个故障转移流程就是为了应对节点故障(这是分区的一种极端形式)而设计的。它允许集群在失去部分节点后,通过副本晋升来恢复完整的服务能力,体现了对分区情况的容错。可用性 (A):在这里,可用性被明确地牺牲了。在故障转移期间,原主节点和其从节点负责的哈希槽会有一小段时间不可用(从节点竞选和晋升的时间)。更重要的是,在网络分区发生时,少数派分区中的所有主节点都会变得不可用。因为它们无法与大多数节点取得联系,为了保证不产生不一致的数据,它们会拒绝所有的写操作和(可能配置为强一致性的)读操作。对于连接到这些节点的客户端来说,服务就是“不可用”的。小结:故障转移机制是 Redis Cluster 选择 CP 的集中体现。它通过依赖“大多数”原则,在发生分区时,宁可让少数派分区的服务停止,也绝不冒险接受可能导致数据不一致的写入。总结与对比  特性/机制数据分片 (Sharding)故障转移 (Failover)综合 CAP 权衡一致性 (C)为局部一致性管理打下基础优先保障:通过“大多数”原则防止脑裂和不一致优先保障 (CP)可用性 (A)提升整体可用性(故障隔离)主动牺牲:故障转移期间及少数派分区服务不可用在网络分区时被牺牲分区容错性 (P)核心设计目标:数据分布以容忍部分故障核心设计目标:在节点故障/分区后自动恢复必须保障 (CP)与 AP 系统(如 Cassandra)的对比:Redis Cluster (CP): 当网络断开,导致主节点和它的从节点被隔离在少数派分区时,这个主节点会停止服务。你的应用会收到错误。数据是安全的,不会出现冲突。Cassandra (AP): 在同样的情况下,被隔离的节点仍然会接受写入。当网络恢复时,Cassandra 会使用诸如“最后写入获胜”等机制来解决冲突,但这可能导致数据丢失。它优先保证服务始终可用,但可能牺牲强一致性。因此,在选择 Redis Cluster 时,你需要明确你的业务场景:是否能接受在网络抖动或节点故障时,部分数据的短暂不可用,以换取数据的强一致性? 如果能,那么 Redis Cluster 的 CP 模型是合适的。如果不能,需要追求高可用,并且可以接受最终一致性,那么可能需要考虑其他方案。
  • [问题求助] Redisson里面的锁是怎么来防止误删的?
    Redisson里面的锁是怎么来防止误删的?
  • [问题求助] Redis中的hash和Java中的HashMap有啥区别
    Redis中的hash和Java中的HashMap有啥区别
  • [问题求助] Redis的ZipList、SkipList和ListPack之间有什么区别?
    Redis的ZipList、SkipList和ListPack之间有什么区别?
  • [问题求助] Redis中的ListPack是如何解决级联更新问题的?
    Redis中的ListPack是如何解决级联更新问题的?
  • [问题求助] ZSet为什么在数据量少的时候用ZipList,而在数据量大的时候转成SkipList?
    ZSet为什么在数据量少的时候用ZipList,而在数据量大的时候转成SkipList?
  • [问题求助] Redis中的setnx和setex有啥区别?
    Redis中的setnx和setex有啥区别?
  • [问题求助] Redis8.0的新特性有哪些?
    Redis8.0的新特性有哪些?
  • [问题求助] Redis中hash结构比string的好处有哪些?
    Redis中hash结构比string的好处有哪些?
  • [问题求助] Redis事务和MySQL事务的区别?
    Redis事务和MySQL事务有什么区别?
  • [问题求助] Redis能完全保证数据不丢失吗?
    Redis能完全保证数据不丢失吗?
  • [问题求助] RDB和AOF的写回策略分别是什么?
    RDB和AOF的写回策略分别是什么?
  • [问题求助] Redisson如何保证解锁的线程一定是加锁的线程?
    Redisson如何保证解锁的线程一定是加锁的线程?也就是如何有效的避免A线程加的锁被B线程解锁?
  • 几招搞定Redis如何高效安全的遍历所有key
    在 Redis 中,高效且安全地遍历所有 key 是一个需要谨慎处理的任务,因为如果操作不当,可能会对 Redis 的性能产生显著影响,尤其是在 key 数量非常庞大的情况下。一、使用 KEYS命令(​​不推荐在生产环境使用​​)命令: KEYS * 说明:KEYS命令会返回匹配指定模式(如 *表示所有 key)的所有 key。​​问题​​:KEYS是 ​​阻塞式操作​​,如果你的 Redis 数据量很大(比如百万级以上的 key),这个命令会一次性将所有 key 加载到内存并返回,这会导致 Redis 长时间阻塞,无法处理其他请求,从而影响线上服务的可用性。结论:❌ ​​严禁在生产环境中使用 KEYS *,尤其是在数据量大的情况下。​​二、使用 SCAN命令(​​推荐方式​​)命令: SCAN cursor [MATCH pattern] [COUNT count] 说明:SCAN是一个 ​​非阻塞的、基于游标的迭代器​​,用于渐进式地遍历 Redis 中的 key。它每次调用返回一小部分 key 和一个新的游标(cursor),你通过不断迭代调用 SCAN,直到游标返回 0,表示遍历完成。相比 KEYS,SCAN对 Redis 性能影响极小,适合生产环境使用。参数:cursor:游标,初始为 0,结束时也为 0。MATCH pattern(可选):匹配特定模式的 key,如 MATCH user:*。COUNT count(可选):建议每次返回的 key 数量,只是一个提示,不保证精确,一般可设为 100~1000。示例(伪代码 / redis-cli): # 第一次调用,cursor 从 0 开始 127.0.0.1:6379> SCAN 0 MATCH * COUNT 100 1) "17" # 下一次迭代的游标 2) 1) "key1" 2) "key2" ... (最多 COUNT 个 key) # 第二次用返回的游标继续 127.0.0.1:6379> SCAN 17 MATCH * COUNT 100 1) "0" # 游标为 0 表示遍历结束 2) 1) "key101" 2) "key102" 优点:✅ ​​非阻塞​​,不会长时间影响 Redis 服务。✅ ​​可控制每次返回的数量​​,降低单次操作开销。✅ ​​支持模糊匹配​​(通过 MATCH)。缺点:⚠️ ​​不保证强一致性​​:在遍历过程中,如果有 key 被增删改,可能会看到重复的 key 或者遗漏某些 key,但对大多数场景是可以接受的。⚠️ ​​需要客户端自行处理游标和多次调用​​。三、结合语言客户端使用 SCAN几乎所有 Redis 官方客户端(如 Python、Java、Node.js 等)都封装了 SCAN的迭代功能,使用起来更加方便。1. Python(redis-py): import redis r = redis.StrictRedis(host='localhost', port=6379, db=0) # 使用 scan_iter 方法(推荐,内部封装了 SCAN) for key in r.scan_iter(match="*", count=100): print(key.decode('utf-8')) scan_iter是一个生成器,会自动处理游标和多次 SCAN 调用,简化开发。2. Java(Jedis)示例: import redis.clients.jedis.Jedis; import redis.clients.jedis.ScanParams; import redis.clients.jedis.ScanResult; public class RedisScanExample { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); String cursor = "0"; ScanParams scanParams = new ScanParams().count(100).match("*"); do { ScanResult<String> scanResult = jedis.scan(cursor, scanParams); for (String key : scanResult.getResult()) { System.out.println(key); } cursor = scanResult.getCursor(); } while (!cursor.equals("0")); } } 四、其他注意事项与建议1. ​​避免在高峰期执行大规模遍历​​即使使用 SCAN,如果 key 数量极大(比如上千万),仍然可能造成一定负载。建议在业务低峰期进行,或者采用分片/分布式方式处理。2. ​​考虑使用 Redis 的 SCAN+ TYPE+ 具体命令​​如果你不仅想遍历 key,还想获取每个 key 的 value 或类型,可以结合 TYPE命令以及 GET/ HGETALL/ SMEMBERS等,但要注意:这会进一步增加 Redis 和客户端的负载。尽量不要在遍历过程中对 key 执行写入或删除操作,避免数据不一致。3. ​​大 key 问题​​如果你的 key 中包含大 value(如大 Hash、大 List 等),在遍历时获取其内容可能导致网络和内存问题,建议提前识别并优化大 key。4. ​​使用 Redis 的 dbsize查看 key 总数(仅总数,不列出 key)​​ 127.0.0.1:6379> DBSIZE (integer) 1234567 这可以让你了解大致有多少 key,为遍历做准备,但注意它只是返回一个近似值。五、总结一下下方法是否阻塞是否推荐适用场景KEYS *是❌ 不推荐仅用于测试或极小数据量环境SCAN否✅ 推荐生产环境,安全遍历所有 key ​​生产环境一定要使用 SCAN,并尽量使用客户端提供的封装方法(如 scan_iter)。​​ 
总条数:553 到第 页
上滑加载中