什么是GEO,有什么用?

GEO就是Geolocation的简写形式,代表地理坐标,Redis GEO 主要用于存储地理位置信息的,帮助我们根据经纬度来检索数据。 它主要支持如下命令: GEOADD:添加一个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member) GEODIST:计算指定的两个点之间的距离并返回 GEOHASH:将指定member的坐标转为hash字符串形式并返回 GEOPOS:返回指定member的坐标 GEORADIUS:指定圆心、半径,找到该圆内包含的所有member,并按照与圆心之间的距离排序后返回。 GEOSEARCH:在指定范围内搜索member,并按照与指定点之间的距离排序后返回。范围可以是圆形或矩形。 GEOSEARCHSTORE:与GEOSEARCH功能一致,不过可以把结果存储到一个指定的key。 扩展知识 使用例子 假设我们想要使用Redis存储和查询几个地点的位置。首先,我们将地点添加到Redis的地理空间集合中,然后我们可以根据位置查询附近的地点。 1 GEOADD locations 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" 这个命令将“Palermo”和“Catania”两个地点添加到名为locations的地理空间集合中。 1 GEORADIUS locations 15 37 100 km WITHDIST 这个命令会查找locations集合中距离经度15、纬度37、100公里范围内的所有地点,并返回它们的名称和距离。 WITHDIST:同时返回找到的项距离指定中心的距离。距离以命令的半径参数指定的单位返回。 WITHCOORD:还会返回匹配项的经度、纬度坐标。 WITHHASH:还会以52位无符号整数的形式返回项的原始geohash编码排序集分数。这只对调试有用,对一般用户来说用处不大。 Redis GEO实现查找附近的人 ✅如何实现"查找附近的人"功能?

March 22, 2026 · 1 min · santu

为什么Lua脚本可以保证原子性?

原子性在并发编程中,和在数据库中是两种不同的概念。 在数据库中,事务的ACID中原子性指的是"要么都执行要么都回滚"。在并发编程中,原子性指的是"操作不可拆分、不被中断"。 Redis既是一个数据库,又是一个支持并发编程的系统,所以,他的原子性有两种。所以,我们需要明确清楚,在问"Lua脚本保证Redis原子性"的时候,指的到底是哪个原子性。 Lua脚本可以保证原子性,因为Redis是单线程执行命令的,当客户端提交一个Lua脚本的时候,Redis会把他当做一个命令来执行,在这个脚本执行期间,不会有其他的命令插入进来执行。 这样就可以保证整个脚本是作为一个整体执行的,中间不会被其他命令插入。但是,如果命令执行过程中命令产生错误,事务是不会回滚的,将会影响后续命令的执行。 也就是说,Redis保证以原子方式执行Lua脚本,但是不保证脚本中所有操作要么都执行或者都回滚。 那就意味着,Redis中Lua脚本的执行,可以保证并发编程中不可拆分、不被中断的这个原子性,但是没有保证数据库ACID中要么都执行要么都回滚的这个原子性。 扩展知识 什么是Lua Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。它提供了非常易于使用的语法,大量的库,以及可移植性,可以用于开发各种各样的应用。Lua是一种高效、轻便、可扩展的脚本语言。它具有语法简洁、操作易学,支持数据结构定义,支持函数式编程,支持面向对象编程,在功能上可以完全取代Shell、Perl,而在轻便性和可扩展性上又具有极大的优势。 Lua脚本语言的优点: 高效性:Lua脚本语言的解释器能够高效的执行脚本,它运行快速,可以实现复杂的程序功能。 简单性:Lua脚本语言是一种小巧的编程语言,它只有一小部分的内部机制,易于学习,用代码就可以轻松实现复杂程序功能。 可移植性:Lua脚本语言可以在多种操作系统上运行,写好的脚本只要移植到其它系统上就可以运行,可以在不同操作系统上使用,可以节省时间和成本。 灵活性:Lua脚本语言具有高度的灵活性,可以实现高效灵活的软件架构,帮助开发者更加精准的实现复杂的需求。 5.安全性:Lua脚本语言的安全性良好,可以保护开发者的代码不受恶意的攻击和恶意的破坏。 以下就是一个Lua脚本,它实现的功能就是转账,通过lua脚本来保证原子性: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 -- 转账操作的Lua脚本(支持指定双方账号) local from_account = KEYS[1] local to_account = KEYS[2] local amount_to_transfer = tonumber(ARGV[1]) -- 检查是否有足够的金额可以转账 local from_balance = tonumber(redis.call("GET", from_account)) if from_balance and from_balance >= amount_to_transfer then -- 执行扣除金额和增加金额的操作 redis.call("DECRBY", from_account, amount_to_transfer) redis.call("INCRBY", to_account, amount_to_transfer) return true else return false end 例如,如果要从account:123转账给account:456,可以这样调用脚本: ...

March 22, 2026 · 1 min · santu

Redis中的setnx命令为什么是原子性的

典型回答 Redis中的setnx命令是一个原子性操作,因为它利用了Redis单线程的特点。 在Redis中,所有的命令都是在主线程中顺序执行的,这意味着每个命令在执行时不会被其他命令打断。当执行setnx命令时,Redis会在内存中检查给定的key是否存在,如果不存在,则设置该key的值,并返回1。如果该key已经存在,则不做任何操作,直接返回0。 由于Redis是单线程的,所以当一个客户端执行setnx命令时,其他客户端无法执行任何命令,直到该命令执行完毕。 因此,setnx命令是一个原子性操作,它可以保证在任何时候只有一个客户端可以执行该命令,这可以防止并发访问造成的数据竞争和不一致性问题。 需要注意的是,虽然setnx命令本身是原子性的,但在实际应用中,多个Redis命令的组合可能会导致数据一致性问题。在这种情况下,开发人员需要使用Redis事务或分布式锁等机制来保证数据的一致性。

March 22, 2026 · 1 min · santu

Redis的持久化机制是怎样的?

典型回答 Redis提供了两种持久化的机制,分别是RDB和AOF。 RDB RDB是将Redis的内存中的数据定期保存到磁盘上,以防止数据在Redis进程异常退出或服务器断电等情况下丢失。 RDB的优点是:快照文件小、恢复速度快,适合做备份和灾难恢复。 RDB的缺点是:定期更新可能会丢数据 AOF AOF是将Redis的所有写操作**追加到AOF文件(Append Only File)的末尾,**从而记录了Redis服务器运行期间所有修改操作的详细记录。当Redis重新启动时,可以通过执行AOF文件中保存的写操作来恢复数据。 但是如果Redis刚刚执行完一个写命令,还没来得及写AOF文件就宕机了,那么这个命令和相应的数据就会丢失了。但是他也比RDB要更加靠谱一些。 AOF的优点是:可以实现更高的数据可靠性、支持更细粒度的数据恢复,适合做数据存档和数据备份。 AOF的缺点是:文件大占用空间更多,每次写操作都需要写磁盘导致负载较高 比较 RDB和AOF在数据可靠性、性能、存储空间占用等方面都有不同的优缺点,具体可以根据实际业务需求和硬件条件来选择合适的持久化机制,或者同时使用两种持久化机制来实现更高的数据可靠性。 特性 RDB AOF 数据可靠性 可能会丢失最后一次快照之后的数据 保证最后一次写操作之前的数据不会丢失 性能 读写性能较高,适合做数据恢复 写性能较高,适合做数据存档 存储空间占用 快照文件较小,占用空间较少 AOF文件较大,占用空间较多 恢复时间 从快照文件中恢复数据较快 从AOF文件中恢复数据较慢 混合持久化 AOF和RDB各自有优缺点,为了让用户能够同时拥有上述两种持久化的优点, Redis 4.0 推出了 RDB-AOF 混合持久化。 在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式追加的文件的末尾。 aof-use-rdb-preamble是开启混合模式的参数 混合持久化结合了 RDB 和 AOF 持久化的优点,开头为 RDB 的格式,使得 Redis 可以更快的启动,同时结合 AOF 的优点,又减低了大量数据丢失的风险。 但是,在AOF 文件中添加了 RDB 格式的内容,使得 AOF 文件的可读性变得很差;如果开启混合持久化,那么此混合持久化 AOF 文件,是不能用在旧版本中的,不向下兼容的。 扩展知识 Redis能完全保证数据不丢失吗? ✅Redis能完全保证数据不丢失吗? ...

March 22, 2026 · 1 min · santu

Redis的虚拟内存机制是什么?

典型回答 Redis提供了一种称为虚拟内存的机制,用于将部分不经常使用的数据存储到磁盘上,从而避免Redis进程占用过多的内存。 但是**需要注意的是,Redis 从 2.4 版本开始已经废弃了虚拟内存(VM)功能,并且在更高版本中不再推荐使用。** 当Redis使用的内存超过了指定的阈值时,虚拟内存机制将自动将一些键值对转移到磁盘上,以释放一部分内存。当需要访问被转移到磁盘上的数据时,虚拟内存机制将自动将数据读取到内存中。 想要配置虚拟内存,需要修改配置文件。主要涉及到以下参数: 1 2 3 4 5 6 maxmemory <num> vm-enabled yes vm-max-memory <num> vm-page-size <num> vm-pages <num> vm-max-threads <num> maxmemory参数用于设置Redis允许使用的最大内存大小,单位为字节。一般来说,建议将maxmemory设置为物理内存大小的一半左右。例如,如果服务器的物理内存为8GB,那么可以将maxmemory设置为4GB。 vm-enabled参数用于启用虚拟内存功能。将其设置为yes即可启用。 vm-max-memory参数用于设置虚拟内存的最大大小,单位为字节。一般来说,建议将vm-max-memory设置为maxmemory的2倍以上。例如,如果maxmemory设置为4GB,那么可以将vm-max-memory设置为8GB以上。 vm-page-size参数用于设置页的大小,单位为字节。一般来说,不需要修改该参数的默认值,即32字节。 vm-pages参数用于设置虚拟内存的页数。一般来说,可以将该参数设置为vm-max-memory/vm-page-size。 vm-max-threads参数用于设置虚拟内存使用的最大线程数。一般来说,建议将该参数设置为服务器的CPU核心数。 但是,还是那句话,没有银弹。**虚拟内存机制虽然可以节省内存,但同时也会带来一定的性能损失。**由于需要将数据从磁盘读取到内存中,因此访问被转移到磁盘上的数据会比访问内存中的数据慢一些。 因此,在实际使用中,需要根据具体的应用场景和硬件条件进行调整,以达到最佳的性能和内存使用效率。 扩展知识 不再建议使用 虚拟内存功能最初被设计为解决物理内存限制的问题,允许Redis将数据分页到磁盘上,只保留常用的数据在内存中。这个功能在初期对于内存受限的环境提供了一定的帮助。 然而,这种设计带来了一些问题: 性能开销:虚拟内存的使用增加了额外的磁盘I/O操作,这会显著降低Redis的性能,因为磁盘访问速度远不如内存访问速度。 复杂性:虚拟内存功能的管理增加了Redis运行的复杂性,尤其是在数据管理和性能调优方面。 技术进步:随着时间的推移,内存价格的下降和服务器内存容量的增加,使得在服务器上配置大量内存变得经济实惠。这减少了对虚拟内存的需求。 因此,Redis的开发团队决定在2.4版本后不再维护或使用虚拟内存功能,并推荐用户使用足够的物理内存来支持Redis实例,或者使用其他策略如数据分片(sharding)来管理大型数据集。这样的变化使得Redis能够专注于其核心优势——提供高性能的内存数据存储服务。

March 22, 2026 · 1 min · santu

Redis 的事务机制是怎样的?

典型回答 Redis中是支持事务的,他的事务主要目的是保证多个命令执行的原子性,即要在一个原子操作中执行,不会被打断。 需要注意的是,Redis的事务是不支持回滚的。从 Redis 2.6.5 开始,服务器将会在累积命令的过程中检测到错误。然后,在执行 EXEC 期间会拒绝执行事务,并返回一个错误,同时丢弃该事务。如果事务执行过程中发生错误,Redis会继续执行剩余的命令而不是回滚整个事务。 Errors happening after EXEC instead are not handled in a special way: all the other commands will be executed even if some command fails during the transaction. https://redis.io/docs/interact/transactions/#errors-inside-a-transaction 更多原子性的解释参考: ✅为什么Lua脚本可以保证原子性? Redis事务相关的命令主要有以下几个: MULTI:标记一个事务块的开始。 DISCARD:取消事务,放弃执行事务块内的所有命令。 EXEC:执行所有事务块内的命令。 UNWATCH:取消 WATCH 命令对所有 key 的监视。 WATCH key [key …]:监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 事务执行时会有什么错误? 前面我们提到过,从 Redis 2.6.5 开始,服务器将会在累积命令的过程中检测到错误。但是后面又说事务执行时也会有错误。这里是不是矛盾了? ...

March 22, 2026 · 1 min · santu

Redis 的过期策略是怎么样的?

典型回答 Redis 通过设置过期时间来控制键值对的生命周期。过期时间可以通过EXPIRE、EXPIREAT、PERSIST等命令设置,也可以在插入数据时直接设置过期时间。 Redis 的过期策略采用的是定期删除和惰性删除相结合的方式。 惰性删除 当一个 key 过期时,不会立即从内存中删除,而是在访问这个 key 的时候才会触发删除操作。Redis会首先检查该键是否设置了过期时间,如果设置了,再检查它是否已经过期。 如果已过期,Redis会立即删除这个键,并返回 nil 给客户端(就像这个键不存在一样)。 如果未过期,则正常返回键的值。 惰性删除只有在键被访问时才会进行过期检查,不会消耗额外的CPU时间来扫描那些长期不被访问的键。 但是,如果一个键已经过期,但永远不再被访问,那么它将永远留在内存中,成为“垃圾数据”,无法被释放。这其实是一种内存泄漏。 定期删除 为了避免惰性删除存在的内存泄漏问题,Redis还提供了定期删除的功能。 Redis 默认每隔 100ms 就随机抽取一些设置了过期时间的 key,并检查其是否过期,如果过期才删除。也就是说每次执行时,并不是扫描所有设置了过期时间的键,而是从相应的过期字典中随机抽取一部分键进行检查。 定期删除是 Redis 的主动删除策略,它可以确保过期的 key 能够及时被删除,但是会占用 CPU 资源去扫描 key,可能会影响 Redis 的性能。 Redis默认同时开启定期删除和惰性删除两种过期策略。 内存释放? 需要注意的是,即使Redis进行了内存回收操作,也不能完全保证被删除的内存空间会立即被系统回收。 Redis并不是直接使用malloc和free来分配和释放每一小块内存,而是使用了自己包装的内存分配器,默认是jemalloc,也可以是libc的ptmalloc2。 内存分配器为了追求效率,会有以下行为: 缓存与池化:当Redis释放(删除)一个键值对时,它只是把这部分内存归还给了它内部的内存分配器。分配器会保留这块内存,并将其放入一个“空闲内存池”中,目的是为了在未来Redis需要分配新的内存时,可以快速地从池中取出复用,而无需每次都向操作系统申请(系统调用是昂贵的)。 碎片化:频繁的分配和释放不同大小的内存块,会导致内存碎片。即使有足够的总空闲内存,也可能因为找不到一块连续的、足够大的内存来满足新的大对象分配请求,从而导致实质上的内存浪费。 归还OS的延迟与不彻底:内存分配器通常不会每次释放内存都立即munmap(解除内存映射)还给操作系统。它只会在满足特定条件时,比如空闲内存块非常大,或者总空闲内存超过某个阈值时,才会将部分内存归还给OS。这是一个权衡,目的是为了性能。 所以,你可能会看到 info memory 命令输出的 used_memory 下降了(因为Redis释放了内存给分配器),但操作系统监测到的 RSS 却下降得很慢甚至不下降。

March 22, 2026 · 1 min · santu

Redis的内存淘汰策略是怎么样的?

典型回答 Redis 的内存淘汰策略用于在内存满了之后,决定哪些 key 要被删除。Redis 支持多种内存淘汰策略,可以通过配置文件中的 maxmemory-policy 参数来指定。 以下是 Redis 支持的内存淘汰策略: noeviction:不会淘汰任何键值对,而是直接返回错误信息。 allkeys-lru:从所有 key 中选择最近最少使用的那个 key 并删除。 volatile-lru:从设置了过期时间的 key 中选择最近最少使用的那个 key 并删除。 allkeys-random:从所有 key 中随机选择一个 key 并删除。 volatile-random:从设置了过期时间的 key 中随机选择一个 key 并删除。 volatile-ttl:从设置了过期时间的 key 中选择剩余时间最短的 key 并删除。 volatile-lfu:淘汰的对象是带有过期时间的键值对中,访问频率最低的那个。 allkeys-lfu:淘汰的对象则是所有键值对中,访问频率最低的那个。 📝介绍下LFU、LRU等缓存失效算法? 扩展知识 如何选择 以下是腾讯针对Redis的淘汰策略设置给出的建议: 当 Redis 作为缓存使用的时候,推荐使用 allkeys-lru 淘汰策略。该策略会将最近最少使用的 Key 淘汰。默认情况下,使用频率最低则后期命中的概率也最低,所以将其淘汰。 当 Redis 作为半缓存半持久化使用时,可以使用 volatile-lru。但因为 Redis 本身不建议保存持久化数据,所以只作为备选方案。 阿里云Redis默认是volatile-lru (https://www.alibabacloud.com/help/zh/redis/user-guide/how-does-apsaradb-for-redis-evict-data-by-default ) 腾讯云默认是noeviction,即不删除键。在内存占满后会出现 OOM 问题,所以建议创建好实例后修改淘汰策略,减少 OOM 问题的出现。(https://cloud.tencent.com/document/product/239/90960 )

March 22, 2026 · 1 min · santu

什么是大Key问题,如何解决?

Big Key是Redis中存储了大量数据的Key,不要误以为big key只是表示Key的值很大,他还包括这个Key对应的value占用空间很多的情况,通常在String、list、hash、set、zset等类型中出现的问题比较多。其中String类型就是字符串的值比较大,而其他几个类型就是其中元素过多的情况。 Redis的Big Key可能存在以下几个危害: **1、影响性能:**由于big key的values占用的内存会很大,所以读取它们的速度会很慢,会影响系统的性能。 2、占用内存: 大量的big key也会占满Redis的内存,让Redis无法继续存储新的数据,而且也会导致Redis卡住 **3、内存空间不均匀:**比如在 Redis 集群中,可能会因为某个节点上存储了Big Key,导致多个节点之间内存使用不均匀。 **4、影响Redis备份和恢复:**如果从RDB文件中恢复全量数据时,可能需要大量的时间,甚至无法正常恢复。 **5、搜索困难:**由于大key可能非常大,因此搜索key内容时非常困难,并且可能需要花费较长的时间完成搜索任务。 **6、迁移困难:**大对象的迁移和复制压力较大,极易破坏缓存的一致性 **7、过期执行耗时:**如果 Bigkey 设置了过期时间,当过期后,这个 key 会被删除,而大key的删除过程也比较耗时 对于Big Key问题的处理,重点要在识别和解决上面。 扩展知识 多大算大? Redis中多大的key算作大key并没有一个固定的标准,因为这主要取决于具体的场景和应用需求。一般来说,如果一个key的value比较大,占用的内存比较多,或者某个key包含的元素数量比较多,这些都可以被认为是大key。 通常情况下,建议不要超过以下设定,超过这些数量就可能会影响Redis的性能。 对于 String 类型的 Value 值,值超过 5MB(腾讯云定义是10M,阿里云定义是5M,我认为5M合适一点)。 对于 Set 类型的 Value 值,含有的成员数量为 10000 个(成员数量多)。 对于 List 类型的 Value 值,含有的成员数量为 10000 个(成员数量多)。 对于 Hash 格式的 Value 值,含有的成员数量 1000 个,但所有成员变量的总 Value 值大小为 100MB(成员总的体积过大)。 但是,这些并不是绝对的限制,而是一个经验值,具体的情况还需要根据应用场景和实际情况进行调整。 识别big key 在识别方面,Redis中的big key可以识别的程序是“redis-cli”,用户可以通过在终端中输入“redis-cli –bigkeys” 来获取Redis中的big key。当redis-cli被调用时,它将搜索所有Redis数据库中包含大量内存数据的key,并且会将其保存在本地标准输出文件中: 1 2 3 4 5 6 7 8 9 # Scanning the entire keyspace to find biggest keys as well as # average sizes per key type. You can use -i 0.1 to sleep 0.1 sec # per 100 SCAN commands (not usually needed). Biggest string found so far 'mykey' with 160012 bytes Biggest list found so far 'mylist' with 2304 items Biggest set found so far 'myset' with 1230 members Biggest zset found so far 'myzset' with 3220 members Biggest hash found so far 'myhash' with 412 fields 处理Big Key 想要解决Big Key的问题,根据具体的业务情况有很多不同的方案,下面简单列几个: ...

March 22, 2026 · 1 min · santu

什么是热Key问题,如何解决热key问题

典型回答 当我们使用Redis作为存储时,如果发生一些特殊情况,比如明星官宣的突发事件,世界杯等重大活动,双十一的活动秒杀等等,就会出现特别大的流量,并且会导致某些热词、商品等被频繁的查询和访问。 如果在同一个时间点上,Redis中的同一个key被大量访问,就会导致流量过于集中,使得很多物理资源无法支撑,如网络带宽、物理存储空间、数据库连接等。 这也是为什么某某明星官宣之后,微博上面就会出现宕机的情况。有时候这种宕机发生后,其他功能都是可以使用的,只是和这个热点有关的内容会无法访问,这其实就和热点数据有关系了。 对于热key的处理,主要在于事前预测和事中解决。 对于事前预测就是根据一些根据经验,提前的识别出可能成为热key的Key,比如大促秒杀活动等。 在事中解决方面,主要可以考虑,热点key拆分、多级缓存、热key备份、限流等方案来解决。 扩展知识 多热算热,给个标准? 到底"多热算热",这个其实需要根据实际的业务情况以及你自己的缓存服务器的整体存储情况而定的。 JD有一个框架叫做hotkey,他就是专门做热key检测的,他的热key定义是在单位时间内访问超过设定的阈值频次就是热key,这个阈值需要业务自己设定,并不断的调整和优化。 热key的定义,通常以其接收到的Key被请求频率来判定,例如: QPS集中在特定的Key:Redis实例的总QPS为10,000,而其中一个Key的每秒访问量达到了7,000。那么这个key就算热key了。 带宽使用率集中在特定的Key:对一个拥有1000个成员且总大小为1 MB的HASH Key每秒发送大量的HGETALL操作请求。 CPU使用时间占比集中在特定的Key:对一个拥有10000个成员的Key(ZSET类型)每秒发送大量的ZRANGE操作请求。 识别热Key 想要解决热key的问题,首先要想办法识别出哪些key是热key。主要由以下几个方案: 根据经验,提前预测 这种方法在大多数情况下还是比较奏效的。比较常见的就是电商系统中,会在做秒杀、抢购等业务开始前就能预测出热key。 但是,这种方式的局限性也很大,就是有些热key是完全没办法预测的,比如明星什么时候要官宣这种事情就无法预测。 实时收集 还有一种热点数据的发现机制,那就是实时的做收集,比如在客户端、服务端或者在代理层,都可以对实时数据进行采集,然后进行统计汇总。 达到一定的数量之后,就会被识别为热key。 具体的收集方式也有很多种,可以在客户端进行收集、也可以在统一代理层进行收集、还可以通过redis的自带命令进行收集。redis 4.0.3中提供了redis-cli的热点key发现功能,执行redis-cli时加上–hotkeys选项即可。 多级缓存 解决热key问题最主要的方式就是加缓存。通过缓存的方式尽量减少系统交互,使得用户请求可以提前返回。 这样即能提升用户体验,也能减少系统压力。 缓存的方式有很多,有些数据可以缓存在客户的客户端浏览器中,有些数据可以缓存在距离用户就近的CDN中,有些数据可以通过Redis等这类缓存框架进行缓存,还有些数据可以通过服务器本地缓存进行。 这种使用多个缓存的情况,就组成了二级缓存、三级缓存等多级缓存了。总之,通过缓存的方式尽量减少用户的访问链路的长度。 热key备份 有了缓存之后,还会带来一个问题,那就是热点数据如果都被缓存在同一个缓存服务器上,那么这个服务器也可能被打挂。 所以,很多人在加了缓存之后, 还可能同时部署多个缓存服务器,如Redis同时部署多个服务器集群。并且实时的将热点数据同步分发到多个缓存服务器集群中,一旦有的集群扛不住了,立刻做切换。 热key拆分 将一个热key拆分成多个key,在每一个Key后面加一个后缀名,然后把这些key分散到多个实例中。 这样在客户端请求的时候,可以根据一定的规则计算得出一个固定的Key,这样多次请求就会被分散到不同的节点上了。 比如 <淄博烧烤> 是个热点key, 把他拆分成淄博烧烤_0001、淄博烧烤_0002、淄博烧烤_0003、淄博烧烤_0004,然后把它们分别存储在cluster中的不同节点上,这样用户在查询<淄博烧烤>的时候,先根据用户ID算出一个下标,然后就访问其中一个节点就行了 有人问了,这不是意味着一个用户只能拿到部分数据了吗?确实是,但是有时候我们并不一定就需要全部的数据。 比如说,同样的两个用户在刷抖音,都想看<淄博烧烤>这个热点相关的视频,但是我们并不一定要给所有用户都推送同样的内容,完全可以把这个词条下面的无数个视频分散存储在不同的节点上,然后给不同的用户推送在不同的节点上的数据就行了。 然后在这个热点key没那么热了之后,再把数据做一下汇总,挑选出一下好的视频在重新推送给没推送到的用户就行了

March 22, 2026 · 1 min · santu

留言给博主