乐趣区

关于redis:Redis服务支持5000万的QPS有什么好的思路

一、题目剖析

1. 仅依据 qps 计算多少机器是不够的

如果一个 Redis 服务器反对五千万下面的读写申请,那么此题很简略,一个机器,一个 Redis 过程即可。

但显然没有这样的超级机器,Redis 也做不到一个过程就能解决五千万 QPS。

那么一个 Redis 到底能解决多少 QPS?

如果是简略的读写,那么一个 Redis 在一个硬件服务器(只有 1 个核,CPU 为以后支流即可),就能解决 Million 级别的 QPS,即至多百万。

所以,下面的问题如同简略了,咱们只有用 50 个 Redis 过程就能反对题目所需的五千万,而后在一个 50 核的机器上跑这五十个过程,即可。

所以,答案如同很简略: 一台五十核机器,五十 Redis 过程。

然而这样的吗?不是的,因为很可能应用环境并不是只有简略的有限量的 key,如果 key 一直增多,那就会呈现大麻烦。

2. 瓶颈在哪?

难点在那个两千万 QPS 的写入(即 20M qps write),我来仔细分析给你看。

假如:每个写入是 100 字节(即 key+value 之和均匀在 100Bytes,即 0.1KB),而且万一这两千万 QPS 的写入都是新增数据,而且随后的三千万 QPS(即 30M qps read)还可能查历史的数据,咱们会有什么麻烦?

显然,下一秒将产生 0.1KB 20M qps = 2GB 新增数据,每天将产生 2GB 86400 秒 = 173 TB 新增数据。

没有任何一台机器的内存能够反对一天的新增数据容量,更何况服务运行工夫以年为单位。

所以,咱们只能用到磁盘。

但问题是:如果将数据存盘,Redis 是查不到的。

但如果 Redis 能查到磁盘上的数据,是否能解此题?

RedRock 反对 Redis 存储磁盘,那么咱们尝试用 RedRock 解解此题。

二、首先拆分

假如咱们用 100 台机器,每台跑一个 RedRock 服务过程。即一个 RedRock 服务,反对 500K qps,其中 200K qps write,300K qps read。这样百台机器就能够达到五千万(50M)qps。

首先,每天新增的数据对于每台机器,只有 1.7 TB,须要存盘。再加上 RedRock 采纳压缩存盘,尽管压缩率依据数据的不同而压缩效率不一样,但最差的状况下,咱们也有信念取得至多 50% 的压缩率(最好能够到 10%)。

所以,对于每台机器,每天会新增最多 0.9 TB 数据,而后入磁盘。一年的数据能够到 300 TB 这个量级。

这个是磁盘的理论最大量,古代的机器配置齐全反对一年这个规模的数据存盘。

但理论利用中,很多时候用不到这么大量,可能会有十倍到百倍甚至千倍的缩减,请急躁看上面的剖析。

三、查看磁盘带宽够否

下面的剖析还太简略,因为磁盘还有一个瓶颈,就是读写速度是否够?

1. 先看磁盘写

对于每台机器,注入的速度是:0.1 KB * 200K qps = 20MB/ 每秒 的注入速度。

再思考 RedRock 用了 RocksDB 写入,个别会有 10 倍的写放大,所以,磁盘写所消耗的带宽是 200MB/ 每秒,再思考压缩 50%,则只有 100MB/ 每秒的写入。

这个对于以后的 SSD 的性能要求是足够的。

2. 再看磁盘读

30M qps read 摊派到 100 台机器,那么每台机器是 300K qps read。

咱们假如 90% 的读,都是热数据,即都在 RedRock 的内存中间接读取,那么只有 10% 的读须要到磁盘上。那么理论磁盘的读的带宽需要是(还需思考 50% 的压缩):

30K qps read from disk 0.1 KB 50% = 1.5MB read/ 每秒

必定也够

3. 磁盘读写一起看

对于写的 100MB/ 每秒,RocksDB 是程序 sequential 模式。

对于读的 1.5MB/ 每秒,RocksDB 是随机 random 模式。

混用是否够,须要测试,因为每个 SSD 对于读写混合模式的反对是不同的

但我本人的大抵判断是:够!不过,倡议你最好测试一下。

四、查看热数据的内存容量

还有一个中央须要查看,就是热数据的量,因为热数据都在内存里。

因为每台机器每秒的新注入数据是:20MB。而新写入的数据个别都是热数据。

所以,如果咱们心愿 90% 的拜访都落在内存里,那么如果是 20G 内存,咱们能够包容最近 1000 秒的数据,即 17 分钟。

即如果是 20G 内存,咱们心愿读 read 的 90% 都产生在最近新注入的 17 分钟的数据上。

如果能够扩充到 200G 内存,那么,就是 170 分钟,也就是近三个小时。

五、查看 key 的内存容量

留神,RedRock 须要将所有的 key 都存储在内存里。所以,咱们还须要算算 key 占用多少内存。

对于每台机器,每秒新进入 200K 个 key。

假如 key 用 16 个字节表白(UUID),那么,每秒将产生 3M 字节的 key 内存,一天将产生 276G 的 key 放在内存里。

所以,真正麻烦的中央是 key 的内存容量。

解决的方法有几个:

扩充机器数量,如果机器是一千台,那么每天每台机器只产生不到 30G 的 key 内存量

心愿 key 不都是新 key,即有很多反复的,比方:每天的写入里,只有 10% 的新 key,则一天新增的 key 量,对于 100 台机器,也就不到 30G,1000 台机器,不到 3G。如果每天的写入,只有 1% 的新 key,则再升高 10 倍。留神:依据业务理论状况,运行越久,则 1% 的产生概率越高,即可能产生第一天是 10% 新增,而后开始递加,最初到一个稳固值 1%,甚至更低。

不论如何,咱们都必须删除过老的 key 了。对于 100 台机器组成的集群(每台机器有 300G 内寄存 key),每天只有 10% 的新 key,则可放 10 天的 key,每天只有 1% 的新 key,则能够放 100 天。对于 1000 台机器集群,则别离是 100 天(三分之一年)和 1000 天(三年)。过老的 key,咱们必须删除,让 key 的内存空间缩小。

同样地,如果每天新增的 key 量,只占写入 qps 的 10% 或者 1%,那么磁盘的容量,一年也不须要下面剖析的 300TB 这个量级,而是同样升高 10 倍,或者 100 倍,即最低只需几个 TB 的磁盘。

六、客户端如何均分负载

上面咱们须要让客户端平均调配负载到这 100 台机器上。

有三个解决方案:

1. 客户端逻辑做 Shard

最简略的算法是:Shard(key) module 100,比方:咱们能够用 CRC16 算法,即 node id = crc16(key) % 100。

益处是:简略。害处是:动静扩大(比方:减少、缩小一台机器)不不便

2. 通过代理 proxy 做 Shard

通过应用诸如 Envoy 这样的代理 (proxy),让代理软件做 shard,而且还能够实现一致性 Shard(consistent hash),这样集群的增减会简略一些。

害处在于,通过 proxy,会减少一些时延。不过 Envoy 采纳 side car 模式,实践上减少最低几十个 us,个别状况下,不会超过 1ms 的时延,所以,还是能够思考的。

3. 用 Redis Cluster

RedRock 反对 Redis 的 Cluster 模式。所以,间接应用 Redis Cluster,增减机器都绝对简略。

害处是:如果机器到了千台,不易做 Redis Cluster,因为其 Gossip 协定在这个量级,问题比拟大。如果是百台机器,则无问题。

七、如果 key+value 超过百字节

如果 value 比拟大,比方均匀千字节,那么下面的算法还是成立,只是,须要依据 value 扩充了 10 倍,相应地,推算(和测试)磁盘的带宽需要以及热数据的内存需要,即下面的百台机器,可能须要变成千台。

八、用 zstd 压缩算法进一步减小磁盘

RedRock 用 RocksDB 库时,以后代码里只反对了 lz4 的压缩算法。

实际上,咱们能够用 zstd 算法对于磁盘里的 LSM 树的最底层进行压缩,这样,将大大减少磁盘的容量,缩小多少,请测试。

当然,你须要减少几行代码,让 RedRock 反对 zstd 压缩,具体可自行批改 src/rock.c 里的 init_rocksdb() 函数。为了让 RedRock 依赖的库较少,我没有减少这个个性,你能够自行退出 zstd 反对,几行代码,并不简单。

九、热数据的拜访不是 90% 会如何

下面假如 90% 的拜访还是热数据,但万一是 80%,甚至 70%,会如何?

如果你仔细阅读了 RedRock 的文档,答案也很简略:

要么时延 Latency 变差,不能保障 P99 还是 1ms 以下。

要么 Throughput 变差,即每台服务器不能反对 500K qps,这时,须要减少机器。

具体如何,请测试,我也不晓得。

十、如何增强高可用性 HA

尽管咱们能够通过 Proxy 和 Redis Cluster,动静地减少机器,但这个过程并不简略,而且有肯定危险(TB 级的数据从一台机器转移到另外一台或多台机器上,不是一个简略的事)。

所以,思考增强高可用 HA,是一个值得思考的计划。

这时,就须要用到 Master/Slave,即读写拆散。

RedRock 反对 Redis 的读写拆散和各种集群计划,所以,对于每个 shard,咱们都能够再补充一台机器做 slave,这样就进步了 HA。

还有一个益处,对于写,加了 slave 并不能 scale out。但对于读,确能够做到 scale out。比方,对于下面的百台机器,如果咱们再减少百台机器做 slave 的话,那么每台机器所接受的读,能够升高到 150K qps。

退出移动版