mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-11-06 01:54:10 +00:00
Update Redis.md
补充 I/O 线程不处理的连接类型,以及成员上千万时排行榜的拆分。
This commit is contained in:
+5
-1
@@ -374,6 +374,10 @@ ZREVRANK rank:likes article:1001 -- 第几名,从 0 开始
|
||||
|
||||
分值相同时,Redis 按成员名的字典序排列,而业务上通常要求先达到这个分数的排在前面。可以把时间编进分值:分值 = 点赞数 × 10<sup>10</sup> + (10<sup>10</sup> − 达到这个点赞数的秒级时间戳)。例如 article:1001 和 article:1002 都是 520 个赞,时间戳分别为 1793000000 和 1793000300,分值为 5208207000000 和 5208206999700,先达到的 article:1001 排在前面。需要注意的是,分值是双精度浮点数,只能精确表示 2<sup>53</sup> 以内的整数,这种写法下点赞数不能超过约 90 万,更大时要缩短时间部分的位数。
|
||||
|
||||
成员上千万时,一个有序集合就成了[大 Key](缓存.md#大-key-与热-key),按 100 万个约 105 MB 估算,1000 万个约 1 GB。可以按分数段拆成多个有序集合,名次等于分数更高的各段的成员数之和,加上在本段中的名次,加分跨段时把成员移到新的段。
|
||||
|
||||
只需要显示“超过了约百分之多少的用户”时,可以按分数区间计数,用户换分时把旧区间的计数减 1、新区间的加 1,不必把每个成员都放进有序集合。同一区间内谁高谁低无从得知,结果是近似值,区间分得越细越准。
|
||||
|
||||
排行榜被大量用户同时查看时,前 10 名这个键会成为热点。前几名的变化不需要实时反映给每个用户,可以在应用的本地缓存中保存 1 秒,大部分请求不再访问 Redis,见 [多级缓存](缓存.md#多级缓存)。
|
||||
|
||||
### 其它
|
||||
@@ -650,7 +654,7 @@ Redis 用一个线程执行所有命令,仍然很快,原因主要有以下
|
||||
|
||||
Redis 6.0 加入的 I/O 多线程(io-threads,默认关闭)分担的也是这部分开销:多个 I/O 线程并行读取、解析请求和写回响应,命令仍由主线程逐条执行,不会有两个线程同时修改一个键。6.0 和 7.x 默认只把写回交给 I/O 线程,读取和解析还要打开 io-threads-do-reads,并且主线程分发完任务后要忙等所有 I/O 线程完成。
|
||||
|
||||
8.0 重新实现后,每个 I/O 线程有自己的事件循环,负责普通客户端的读取、解析和写回;命令仍由主线程执行,主从复制、订阅等特殊连接的读写也由主线程处理(8.8 起主从复制的连接也交给 I/O 线程)。8.0 的 io-threads 把主线程也算作一个,例如 io-threads 4 表示主线程加 3 个 I/O 线程。
|
||||
8.0 重新实现后,每个 I/O 线程有自己的事件循环,负责普通客户端的读取、解析和写回;命令仍由主线程执行,主从复制、订阅、MONITOR 和阻塞中的连接这类特殊连接的读写也由主线程处理(8.6 起主从复制的连接在完成全量同步后也交给 I/O 线程)。8.0 的 io-threads 把主线程也算作一个,例如 io-threads 4 表示主线程加 3 个 I/O 线程。
|
||||
|
||||
<div align="center"> <img src="pics/redis-io-threads.png" width="760px"/> </div><br>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user