[转载学习] KV存储引擎的线程模型

205 阅读3分钟

概述

2022 年 6 月 8 日,Redis Inc. 的官方博客发布了一篇名为《13 年后,Redis 是否需要一个新架构?》的文章,提到了Redis面对Dragonfly这类多线程架构的挑战。Tair则是阿里云的商业KV存储。

原文

mp.weixin.qq.com/s/QHK69rNh2…

笔记

单线程存储模型的现实挑战

  1. 节点CPU被打满(内存数据库的瓶颈从IO转移到了CPU),主从无法在此时建立,用户除了对流量降级别无他法
  2. 数据访问存在峰值,导致负载标高,监控程序也因为峰值不工作
  3. 读写分离架构下,高负载下,主从同步链式同步都会断开,更无法使用星式同步
  4. 高负载下,GC不及时,很多应该被淘汰的key没有被淘汰
  5. Redis的内存监控没有分区域,导致不知道各个区域的内存情况,优化也就无从谈起
  6. Pub/Sub性能捉急

Tair的解法

  1. 主从同步放到独立线程,AOF模式彻底binlog化。作者提到:现代存储服务的一个核心设计就是 Binlog,很多特性都是围绕着 Binlog 展开的,有足够多附加信息的 Binlog 才能在多副本一致性以及 CDC 等场景下提供相应的支持。
  2. 存储服务控制流和数据流彻底隔离,包括代码层面和资源层面
  3. 星型同步
  4. 过期数据使用线程扫描,但是前提是存储引擎支持高性能的线程安全,这一点其实才是大难点
  5. 内存引擎本身要做好自己的 Footprint 控制,需要详细的统计清楚自己的数据区域用量,元数据区域用量,各类 buffer 机制的用量
  6. Pub/Sub优化在写专利,不多说

Tair的心法

  1. 如何看待接口兼容?使用和 Redis 完全一致的语义,对外的所有协议/接口直接移植了 Redis 社区的 TCL 测试来保证行为一致
  2. 进一步拓展数据结构:在传统 Redis 的使用场景中,有 KV、List、Hash、Set、Sorted Set、Stream 等数据结构,Tair 也扩展了 TairString(带 version 可以 CAS 的 String)、TairHash(支持 field 带过期的 Hash 结构)、TairZSet(多维排序集合)、TairDoc(Json 格式数据)、TairBloom(Bloom 过滤器)、TairTS(时序数据)、TairGIS(R-Tree 地理位置)、TairRoaring(Roaring Bitmap)、TairCPC(Compressed Probability Counting)以及 TairSearch(搜索)等等高级数据结构
  3. 警惕时间复杂度随量级增大的慢接口使用
  4. 关于事务:比较成熟的并发协议有:轻量锁、时间戳、多版本、串行等方式。大多数的 Redis 兼容服务还是采用了轻量锁的方案,这样比较容易做到兼容,但是这样还不够。
  5. 慢查询隔离:得益于多线程,可以有fastpath,slowpath,slowestpath,引入协程处理慢查询,慢查询也要做优先级,FCFS不可取
  6. Lua使用多线程加速,使用严格模式,避免死锁,优化锁粒度