You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
10 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 40 | Redis的下一步基于NVM内存的实践
你好,我是蒋德钧。
今天这节课是咱们课程的最后一节课了我们来聊聊Redis的下一步发展。
这几年呢新型非易失存储Non-Volatile MemoryNVM器件发展得非常快。NVM器件具有容量大、性能快、能持久化保存数据的特性这些刚好就是Redis追求的目标。同时NVM器件像DRAM一样可以让软件以字节粒度进行寻址访问所以在实际应用中NVM可以作为内存来使用我们称为NVM内存。
你肯定会想到Redis作为内存键值数据库如果能和NVM内存结合起来使用就可以充分享受到这些特性。我认为Redis发展的下一步就可以基于NVM内存来实现大容量实例或者是实现快速持久化数据和恢复。这节课我就带你了解下这个新趋势。
接下来我们先来学习下NVM内存的特性以及软件使用NVM内存的两种模式。在不同的使用模式下软件能用到的NVM特性是不一样的所以掌握这部分知识可以帮助我们更好地根据业务需求选择适合的模式。
## NVM内存的特性与使用模式
Redis是基于DRAM内存的键值数据库而跟传统的DRAM内存相比NVM有三个显著的特点。
首先,**NVM内存最大的优势是可以直接持久化保存数据**。也就是说数据保存在NVM内存上后即使发生了宕机或是掉电数据仍然存在NVM内存上。但如果数据是保存在DRAM上那么掉电后数据就会丢失。
其次,**NVM内存的访问速度接近DRAM的速度**。我实际测试过NVM内存的访问速度结果显示它的读延迟大约是200~300ns而写延迟大约是100ns。在读写带宽方面单根NVM内存条的写带宽大约是1~2GB/s而读带宽约是5~6GB/s。当软件系统把数据保存在NVM内存上时系统仍然可以快速地存取数据。
最后,**NVM内存的容量很大**。这是因为NVM器件的密度大单个NVM的存储单元可以保存更多数据。例如单根NVM内存条就能达到128GB的容量最大可以达到512GB而单根DRAM内存条通常是16GB或32GB。所以我们可以很轻松地用NVM内存构建TB级别的内存。
总结来说NVM内存的特点可以用三句话概括
* 能持久化保存数据;
* 读写速度和DRAM接近
* 容量大。
现在业界已经有了实际的NVM内存产品就是Intel在2019年4月份时推出的Optane AEP内存条简称AEP内存。我们在应用AEP内存时需要注意的是AEP内存给软件提供了两种使用模式分别对应着使用了NVM的容量大和持久化保存数据两个特性我们来学习下这两种模式。
第一种是Memory模式。
这种模式是把NVM内存作为大容量内存来使用的也就是说只使用NVM容量大和性能高的特性没有启用数据持久化的功能。
例如我们可以在一台服务器上安装6根NVM内存条每根512GB这样我们就可以在单台服务器上获得3TB的内存容量了。
在Memory模式下服务器上仍然需要配置DRAM内存但是DRAM内存是被CPU用作AEP内存的缓存DRAM的空间对应用软件不可见。换句话说**软件系统能使用到的内存空间就是AEP内存条的空间容量**。
第二种是App Direct模式。
这种模式启用了NVM持久化数据的功能。在这种模式下应用软件把数据写到AEP内存上时数据就直接持久化保存下来了。所以使用了App Direct模式的AEP内存也叫做持久化内存Persistent MemoryPM
现在呢我们知道了AEP内存的两种使用模式那Redis是怎么用的呢我来给你具体解释一下。
## 基于NVM内存的Redis实践
当AEP内存使用Memory模式时应用软件就可以利用它的大容量特性来保存大量数据Redis也就可以给上层业务应用提供大容量的实例了。而且在Memory模式下Redis可以像在DRAM内存上运行一样直接在AEP内存上运行不用修改代码。
不过有个地方需要注意下在Memory模式下AEP内存的访问延迟会比DRAM高一点。我刚刚提到过NVM的读延迟大约是200~300ns而写延迟大约是100ns。所以在Memory模式下运行Redis实例实例读性能会有所降低我们就需要在保存大量数据和读性能较慢两者之间做个取舍。
那么当我们使用App Direct模式把AEP内存用作PM时Redis又该如何利用PM快速持久化数据的特性呢这就和Redis的数据可靠性保证需求和现有机制有关了我们来具体分析下。
为了保证数据可靠性Redis设计了RDB和AOF两种机制把数据持久化保存到硬盘上。
但是无论是RDB还是AOF都需要把数据或命令操作以文件的形式写到硬盘上。对于RDB来说虽然Redis实例可以通过子进程生成RDB文件但是实例主线程fork子进程时仍然会阻塞主线程。而且RDB文件的生成需要经过文件系统文件本身会有一定的操作开销。
对于AOF日志来说虽然Redis提供了always、everysec和no三个选项其中always选项以fsync的方式落盘保存数据虽然保证了数据的可靠性但是面临性能损失的风险。everysec选项避免了每个操作都要实时落盘改为后台每秒定期落盘。在这种情况下Redis的写性能得到了改善但是应用会面临秒级数据丢失的风险。
此外当我们使用RDB文件或AOF文件对Redis进行恢复时需要把RDB文件加载到内存中或者是回放AOF中的日志操作。这个恢复过程的效率受到RDB文件大小和AOF文件中的日志操作多少的影响。
所以在前面的课程里我也经常提醒你不要让单个Redis实例过大否则会导致RDB文件过大。在主从集群应用中过大的RDB文件就会导致低效的主从同步。
我们先简单小结下现在Redis在涉及持久化操作时的问题
* RDB文件创建时的fork操作会阻塞主线程
* AOF文件记录日志时需要在数据可靠性和写性能之间取得平衡
* 使用RDB或AOF恢复数据时恢复效率受RDB和AOF大小的限制。
但是如果我们使用持久化内存就可以充分利用PM快速持久化的特点来避免RDB和AOF的操作。因为PM支持内存访问而Redis的操作都是内存操作那么我们就可以把Redis直接运行在PM上。同时数据本身就可以在PM上持久化保存了我们就不再需要额外的RDB或AOF日志机制来保证数据可靠性了。
那么当使用PM来支持Redis的持久化操作时我们具体该如何实现呢
我先介绍下PM的使用方法。
当服务器中部署了PM后我们可以在操作系统的/dev目录下看到一个PM设备如下所示
```
/dev/pmem0
```
然后我们需要使用ext4-dax文件系统来格式化这个设备
```
mkfs.ext4 /dev/pmem0
```
接着,我们把这个格式化好的设备,挂载到服务器上的一个目录下:
```
mount -o dax /dev/pmem0 /mnt/pmem0
```
此时我们就可以在这个目录下创建文件了。创建好了以后再把这些文件通过内存映射mmap的方式映射到Redis的进程空间。这样一来我们就可以把Redis接收到的数据直接保存到映射的内存空间上了而这块内存空间是由PM提供的。所以数据写入这块空间时就可以直接被持久化保存了。
而且如果要修改或删除数据PM本身也支持以字节粒度进行数据访问所以Redis可以直接在PM上修改或删除数据。
如果发生了实例故障Redis宕机了因为数据本身已经持久化保存在PM上了所以我们可以直接使用PM上的数据进行实例恢复而不用再像现在的Redis那样通过加载RDB文件或是重放AOF日志操作来恢复了可以实现快速的故障恢复。
当然因为PM的读写速度比DRAM慢所以**如果使用PM来运行Redis需要评估下PM提供的访问延迟和访问带宽是否能满足业务层的需求**。
我给你举个例子带你看下如何评估PM带宽对Redis业务的支撑。
假设业务层需要支持1百万QPS平均每个请求的大小是2KB那么就需要机器能支持2GB/s的带宽1百万请求操作每秒 \* 2KB每请求 = 2GB/s。如果这些请求正好是写操作的话那么单根PM的写带宽可能不太够用了。
这个时候我们就可以在一台服务器上使用多根PM内存条来支撑高带宽的需求。当然我们也可以使用切片集群把数据分散保存到多个实例分担访问压力。
好了到这里我们就掌握了用PM将Redis数据直接持久化保存在内存上的方法。现在我们既可以在单个实例上使用大容量的PM保存更多的业务数据了同时也可以在实例故障后直接使用PM上保存的数据进行故障恢复。
## 小结
这节课我向你介绍了NVM的三大特点性能高、容量大、数据可以持久化保存。软件系统可以像访问传统DRAM内存一样访问NVM内存。目前Intel已经推出了NVM内存产品Optane AEP。
这款NVM内存产品给软件提供了两种使用模式分别是Memory模式和App Direct模式。在Memory模式时Redis可以利用NVM容量大的特点实现大容量实例保存更多数据。在使用App Direct模式时Redis可以直接在持久化内存上进行数据读写在这种情况下Redis不用再使用RDB或AOF文件了数据在机器掉电后也不会丢失。而且实例可以直接使用持久化内存上的数据进行恢复恢复速度特别快。
NVM内存是近年来存储设备领域中一个非常大的变化它既能持久化保存数据还能像内存一样快速访问这必然会给当前基于DRAM和硬盘的系统软件优化带来新的机遇。现在很多互联网大厂已经开始使用NVM内存了希望你能够关注这个重要趋势为未来的发展做好准备。
## 每课一问
按照惯例我给你提个小问题你觉得有了持久化内存后还需要Redis主从集群吗?
欢迎在留言区写下你的思考和答案,我们一起交流讨论。如果你觉得今天的内容对你有所帮助,也欢迎你分享给你的朋友或同事。