5

《Redis深度历险》学习笔记:线程模型&持久化

 3 years ago
source link: https://acuario.xyz/posts/redis-deep-adventure-thread-model-and-persistence/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

《Redis深度历险》学习笔记:线程模型&持久化

 2020.8.10 2020.8.10  学习笔记/Redis  1445  3 分钟

线程模型

非阻塞IO

  • Redis、Node.js、Nginx 均是单线程服务,但他们都是服务器高性能的典范。
  • Redis 4.0 版本抛弃了单线程设计,转为多线程设计,但其主处理程序依然是单线程模型
  • Redis 使用单线程进行设计的原因:
    • 更好的可维护性,方便开发和调试:多线程模型存在竞争条件 (race condition)问题,多个进行的执行顺序会对共享内存的内容造成影响,需要额外设计锁逻辑。
    • 处理并发请求:将数据库的开、关、读、写都转换成了事件,使用 I/O 多路复用 机制轮询描述符处理并发连接,同时等待多个连接发送的请求。
    • Redis 服务中运行的绝大多数操作的性能瓶颈都不是 CPU:一个 Redis 服务在 1s 内可处理 100w 个用户请求,如无法满足,应使用分片将不同的请求交给不同的 Redis 服务器来处理,而不是在同一个 Redis 服务中引入大量的多线程操作。
  • 每一个网络连接都会产生一个文件描述符,并由执行事件循环(死循环)的多路复用模块接收,然后关联指令队列,交给文件事件分配器按顺序处理。一旦期间有任何事件到来,就可以立即返回。时间过了之后还是没有任何事件到来,也会立即返回。
    多路复用
    (Source: Redis 和 I/O 多路复用)
  • 关于异步阻塞的概念,这篇文章有一个形象的举例:

    出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
    
    同步阻塞:老张把水壶放到火上,立等水开。
    
    同步非阻塞:老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。
    
    异步阻塞:老张把响水壶放到火上,立等水开。
    
    异步非阻塞:老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。
    

持久化

RDB 快照

  • RDB 快照是一次全量备份,是内存数据的二进制序列化形式,在存储上非常紧凑。
  • 持久化需要进行文件 IO,但该操作不能使用多路复用 API,在拖慢性能的同时,还存在数据一致性的问题(脏读、幻读等),为避免上述问题,Redis 使用多进程 COW(Copy On Write)策略进行持久化。
  • 创建快照(持久化)时:
    • fork(多进程)函数使进程分离,产生父、子进程,双方共享内存数据,内存里的数据在进程产生的一瞬间就凝固。
    • 父进程持续处理数据,复制需要修改的数据端后进行操作,不改变原有数据端。
    • 子进程持续读取数据端内数据进行快照操作,读写数据到一个临时文件 RDB 中。
    • 子进程完成读写后替换原 RDB 文件。

AOF 日志(Append-Only File)

  • AOF 日志是顺序指令序列,只记录对内存进行修改的指令记录。
  • Redis 通常先执行命令,再记录 AOF 日志

AOF 重写

  • 长期运行会使 AOF 日志文件过大,重放日志耗时过长,AOF 重写操作可为文件瘦身。
  • 运行机制:
    • fork(多进程)函数使进程分离,产生父、子进程
    • 子进程将日志写入到一个临时文件 AOF 中
    • 父进程将数据变更写入到临时内存缓冲区,同时持续写入日志到原 AOF 文件中(这样即使断电,也能保证有一个 AOF 文件是可用的)
    • 子进程完成读写后,父进程接收信号,将内存缓冲区日志追加到临时文件 AOF 中
    • 父进程完成写入后替换 AOF 文件,从而实现 AOF 重写。
  • AOF 日志使用 Linux 提供的 fsync 函数进行文件写入操作,但由于文件 IO 速度慢,需要设置适当的写入周期。
  • AOF 日志的 fsync 周期默认为 1s。(服务宕机最多丢失 1s 数据)。可关闭 fsync 牺牲安全性换取 Redis 性能。

Redis 4.0 混合持久化

  • RDB 来恢复内存会丢失大量数据,通常使用 AOF 日志重放,为解决重放太耗时的问题,Redis 4.0 使用混合持久化。
  • 将 RDB 文件和增量 AOF 日志文件存在一起,AOF 日志文件记录持久化过程中的增量变更。重放时,双管齐下甭提有多爽快了!

延伸阅读:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK