大容量 redis 存储方案 --Pika 陈宗志 360 基础架构组技术经理
简介 13 年入职 360 基础架构组 Bada Pika Zeppelin Mario, Pink, slash, floyd https://github.com/qihoo360
概要 存在问题 分析问题 解决问题 Pika vs redis
Introduction Pika 是 DBA 和基础架构团队一起设计开发的大容量 redis 的解决方案 完全兼容 redis 协议, 用户不需要修改任何代码 进行迁移
Pika User Redis 实例数量 :6000+ 个 日访问量 :5000+ 亿 Pika 数据数量 :1000+ 个 日访问量 :1000+ 亿 覆盖率 :80% 以上业务线 单份数据体积 :6.8T
Pika 定位 Pika 的出现并不是为了替代 Redis, 而是 Redis 的场景补充 Pika 力求在完全兼容 Redis 协议 继承 Redis 便 捷运维设计的前提下通过持久化存储的方式解决 Redis 在大容量场景下的问题
Redis 问题 恢复时间长 一主多从, 主从切换代价大 缓冲区写满问题 成本问题
Redis 问题 恢复时间长 50G redis 回复时间 70 分钟 同时开启 aof 和 rdb
Redis 问题 一主多从, 主从切换代价大 主库挂掉后升级从库, 所有的从库全部重传数据
Redis 问题 缓冲区写满问题 内存是昂贵资源, 缓冲区一般设置 2G 网络原因很容易将数据堵死, 那么就会发生大量数据重传
Redis 问题 内存太贵 线上使用的 redis 机器是 64G, 96G. 只使用 80% 的空间. 如果一个 redis 的实例是 50G, 那么基本一台机器只能运行一个 redis 实例. 特别的浪费资源
Redis 问题 90/GB VS 2.6/GB 30 倍的差距
问题分析 成本问题 可用性问题 同步问题 易用性问题
问题分析 尽可能兼容 redis 协议 使用基于磁盘的存储引擎 rocksdb 实现多数据接口接口 网络库 添加 binlog 模块
Pika 整体结构
网络模块 --Pink 基础架构团队开发网络编程库, 支持 pb, redis, pg, http 等协议. 抽象各种不同类型线程 DispatchThread WorkThread BGThread https://github.com/qihoo360/pink
网络模块 --Pink 稳定行, 在各个项目中使用 4 年多 易用性 高性能
网络模块 --Pink class MyPbConn : public pink::pbconn { Public: MyPbConn(int fd, std::string ip_port, pink::thread* self_thread_ptr = NULL) : pink::pbconn(fd, ip_port) { res_ = dynamic_cast<google::protobuf::message*>(&message_); } ~MyPbConn() {} int DealMessage() { message_.parsefromarray(rbuf_ + cur_pos_ - header_len_, header_len_); message_.set_name("hello " + message_.name()); uint32_t u =htonl( message_.bytesize()); memcpy(static_cast<void*>(wbuf_), static_cast<void*>(&u), COMMAND_HEADER_LENGTH); message_.serializetoarray(wbuf_ + COMMAND_HEADER_LENGTH, PB_MAX_MESSAGE); set_is_reply(true); }
网络模块 --Pink
存储引擎 --Nemo Nemo Pika 的存储引擎, 基于 Rocksdb 实现. 实现了 Hash, List, Set, Zset 等数据结构 Rocksdb 启动只需要加载 log 文件 Rocksdb 使用的本地硬盘, 对 SSD 盘友好 https://github.com/qihoo360/nemo
存储引擎 --Nemo
存储引擎 --Nemo HSET myhash field1 "Hello" DB->Put(wop, h6myhashfield1,hello01477671118) DB->Put(wop, Hmyhash11477671118, 6)
存储引擎 --Nemo
存储引擎 --Nemo LPUSH mylist "world" DB->Put(wop, l6mylist6, 57world01477671118) DB->Put(wop, Lmyhash11477671118, 6071)
日志模块 --Binlog Binlog 顺序写文件, 通过 Index + offset 进行同步点 检查 解决了缓冲区小的问题 支持全同步 + 增量同步
日志模块 --Binlog
主从同步 -- slaveof
主从同步 -- slaveof
Pika 遇到问题 秒删 通过修改 Rocksdb, 增加 version, timestamp 字段. 删除只需要修改 metadata 支持亿级别数据秒删
Pika 遇到问题 数据 compact 修改 Rocksdb manual compact 策略, 支持低优先级的 manual compact 根据机型调整 rocksdb 配置, compac 线程, memtable 个数 晚上定期执行
Pika 遇到问题 数据备份 需要 rocksdb 和 Binlog 配合
Pika 运维 线上架构 LVS 读写 VIP LVS 只读 VIP LVS 读写 VIP LVS 读写 VIP Master Master Master Slave Slave Slave Slave Slave 主机房 A 机房 B 机房 A 机房 B
Pika 运维 线上架构 LVS 读写 VIP LVS 只读 VIP LVS 读写 VIP LVS 只读 VIP Master Master 断点续传 Slave1 Slave2 Slave3 Slave1 提升为主库 Slave2 Slave3 主机房 A 机房 B 主机房 A 机房 B
Pika 运维 迁移工具 Redis_to_pika 将 redis 数据迁移到 pika, 基于 aof, 能全量 + 增量方式同步数 据 (Note 关闭 aof 重写 ) Pika_to_redis 业务增长过快,pika 逐渐难以支持性能, 将 pika 迁回 redis, 支持增量数据同步 Ssdb_to_pika 将 ssdb 数据迁移到 pika, 目前不支持增量同步
Pika 运维 案例一 消息推送服务部分 redis 迁移到 pika 迁移前 : SET 数据结构为主 5 套 30G 左右的 redis 主从, 占用 300G 内存 迁移后 : 1 套 50G 左右的 pika 主从, 占用 100 多 G 磁盘
Pika 运维 案例二 数据分析业务 redis 迁移到 pika 迁移前 : 到 40G 业务数据量增长迅速, 上线不到 1 周数据量增长 迁移后 : 1 套 100G+ Pika 主从
Pika 开发现状 Pika 团队目前有 2 个主力开发维护,2 个 DBA 做需求分析讨论 性能测试 bug 跟踪 回归测试 积累 1700+ 个测试用例 产品经理汇总 github 问题和交流群用户反馈, 帮用户问 题解决和需求排期开发 一月一个小版本, 二月一个大版本
Pika 开发现状 双主支持 Pika_hub 提供多机房写入支持 支持 sentinel 支持 codis
Pika 总结 恢复时间长 一主多从, 主从切换代价大 缓冲区写满问题 内存昂贵问题
Pika vs redis 劣势 由于 Pika 是基于内存和文件来存放数据, 所以性能肯定比 Redis 低一些 优势 容量大 加载 db 速度快 备份速度快 对网络容忍度高 性价比高
Pika vs redis - CPU: 24 Cores, Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz MEM: 165157944 kb OS: CentOS release 6.2 (Final) NETWORK CARD: Intel Corporation I350 Gigabit Network Connection
Pika vs redis
Pika vs redis
Pika vs redis 来自 vip 的测试 https://github.com/qihoo360/pika