ssd-cache
来源:互联网 发布:淘宝代理赚钱吗( 编辑:程序博客网 时间:2024/05/04 02:49
源地址:http://idning.github.io/ssd-cache.html
Table of Contents
- 1 需求
- 1.1 why
- 1.2 具体需求
- 2 index
- 3 ssd 特性
- 3.1 成本
- 3.2 接口
- 3.3 比较典型的ssd参数
- 3.4 小结
- 4 现有系统调研
- 4.1 基于redis修改
- 4.1.1 redis-vm
- 4.1.2 redis-storage
- 4.1.3 小结
- 4.2 单机存储引擎
- 4.2.1 LevelDB
- 4.2.2 RocksDB(facebook)
- 4.2.3 Berkley DB
- 4.2.4 nessDB(国人开发)
- 4.2.5 小结
- 4.3 备选项目
- 4.3.1 ssdb
- 4.3.2 fatcache
- 4.3.3 ardb
- 4.3.4 ledisdb
- 4.3.5 其它
- 4.3.6 小结
- 4.4 成熟分布式存储系统
- 4.4.1 淘宝tair
- 4.4.2 aerospike
- 4.4.3 #facebook Apollo
- 4.4.4 #facebook-McDipper
- 4.4.5 #腾讯CKV海量分布式存储系统
- 4.4.6 小结
- 4.5 其它思路
- 4.1 基于redis修改
- 5 小结
- 5.1 关于目前的很多系统
1 需求
1.1 why
用redis内存实在太贵了, 假设要存1T数据双副本:
- 内存: 1000*2 / 64 = 32台机器.
- 2T盘机器: 2-4台
1.2 具体需求
- 数据存放在ssd.
- 性能要求: 6台机器的集群10w/s, (单机2w/s)
- 有expire功能.
- 使用redis协议 (twemproxy, client-lib可以复用)
- 数据类型仅支持kv, 以后可以考虑支持hash.
其它:
- 事务或script支持.
- 主从, failover
- 集群.
- redis-mgr 部署支持
2 index
主要涉及下面几个方面:
- ssd特性.
- 存储引擎, 如LevelDB, RocksDB, BDB等.
- 现有系统的调研和benchmark, 主要关注SSDB和fatcache.
本文是这个调研系列的目录和结论, 相关调研:
- coding-for-ssd笔记
- LevelDB 调研 TODO
- SSDB代码阅读
- SSDB benchmark
- fatcache 代码阅读
3 ssd 特性
3.1 成本
- 实际上, 我们买服务器的时候, 价格会更便宜些, 不过还是这个数量级.
- 考虑到一台1U服务器价格 在3-5w, 使用2T ssd带来的成本上升: 5200/30000 = 18%左右, 并不算太贵, 加之后续电费等消耗, 可以认为使用ssd带来的成本上升小于15%
- 当然, 我们不能用ssd来存文件之类的大/冷的数据, 这是明显的浪费.
3.2 接口
目前ssd主要2种接口:
sata
- pci-e, 性能更高.
- 典型产品如:
- Fusion-io ioScale Gen2 (w: 4w, r:5w)
- Fusion-io ioMemory (w: 32w, r:19w)
- 华为ES3000 (w: 10w, r:15w)
- MemblazeQ520 (w:7w, r:3w)
sata 带宽6Gbps, pci-e 常见带宽 3.2G*8 = 24Gbps.
3.3 比较典型的ssd参数
数据来源:
- Intel-SSD-320: http://ark.intel.com/products/56569/Intel-SSD-320-Series-600GB-2_5in-SATA-3Gbs-25nm-ML
- Intel-SSD-530: http://ark.intel.com/products/75336/Intel-SSD-530-Series-480GB-2_5in-SATA-6Gbs-20nm-MLC
- Fusion-io: http://www.fusionio.com/data-sheets/iomemory-px600-atomic-series/
notes:
这里选的 Fusion-io ioMemory系列, 写可以达到32w/s, 写延迟只有15us, 很明显写操作都是先写buffer.
- 对三块Intel-SSD-530 做raid0后, 用fio进行了测试, 数据和标称数据差不多:
- random-write: 5.5w/s
- random-read: 7.3w/s
3.4 小结
随机读性能好
- 随机写性能较差
写放大: 写一个字节也会导致整个page的read-modify-write
应该尽量避免small-write
- 很多ssd会通过 hybrid log-block mapping 来做写merge. 从而减轻写放大,
- 这相当于把Log-Structure的一些算法在ssd控制器这一层实现了, 从而实现较高的随机写性能.
- 但是即便有了 hybrid log-block mapping, 也应该尽量避免small-write(因为需要多次操作映射关系表)
- ssd在大量写压力下, 性能可能恶化到8000iops.
- 因为很多update, GC可能跟不上, 如果每次写操作需要做一次erase整个block, 就悲剧了.
- 正常情况下, GC利用后台的时间, 可以完成erase工作.
顺序读写和hdd在同一量级.
寿命有限
ssd可以通过下面这些方式调优:
- 调整page/block的大小, 较小的擦除块可以得到较高的wqps.
- gc策略: 可以通过不同的算法优化, 这是ssd控制器FTL的核心技术.
- Flash Translation Layer (FTL) 上做 hybrid log-block mapping 优化随机写.
- 使用 TRIM 命令, 会有少量优化.
详细参考: coding-for-ssd笔记
4 现有系统调研
针对我们的需求, 调研了一些现有的系统, 主要分三类:
- 基于redis的修改如redis-vm.
- 单机引擎如Berkley DB, LevelDB.
- 一些和我们需求接近的现有系统, 如ssdb, fatcache等.
- 成熟产品, 如淘宝tair, aerospike 等.
4.1 基于redis修改
4.1.1 redis-vm
- http://antirez.com/news/52
- http://blog.nosqlfan.com/html/1047.html
redis在2.2-2.4曾经做过vm功能, 来将内存扩展到磁盘, 但是不久就被废弃了, 原因主要是造成性能不稳定.
存在的问题:
- slow restart: 重启太慢
- slow saving: 保存数据太慢
- slow replication: 上面两条导致 replication 太慢
- complex code: 代码过于复杂
- 2.4 之后就已经从redis代码中移除了.
作者的观点:
- have Redis do what it does best - very quickly serve data from RAM.
- 估计当时的测试, 使用的磁盘都是hdd, 那当然性能糟糕, 如果换成ssd应该会好些.
4.1.2 redis-storage
把leveldb嵌入到redis.
完成度较高, 新增了一些rl_开头的命令:
rl系列命令:(同时操作redis和leveldb系列命令)=======string数据操作======rl_get key (从redis或leveldb取值, 优先顺序:redis > leveldb)rl_getset key (返回同rl_get, 当leveldb有值,redis无值时,会回写到redis)...
读: 先从redis读取, 如果redis没有,则到leveldb读取。
写: 先写到leveldb中,写成功了,再写到redis中
- 问题:
这个项目的目的是把redis的内存扩大2-5倍, 把redis作为leveldb的cache+store. 两份storage很诡异.
- 作者设计的时候, 应该是考虑到兼容redis, 客户端尽量不需要改动, 冷key会自动淘汰,
- 但是实际上提供了两套命令, 客户端需要根据情况, 指定只写redis/只写leveldb还是双写. 就很麻烦.
没有expire支持, leveldb过大后, 怎么办?
完全没有考虑到主从的设计.
参考:
- https://github.com/qiye/redis-storage
- http://www.guangla.com/post/2014-03-17/40061277735 (shenzhe)
4.1.3 小结
基于redis的改进, 主要有这么几种:
- 增加新命令
- 在key被淘汰时写磁盘
- key一直在内存, 把某些value放磁盘(redis-vm的实现方案)
如果基于redis来实现, 存在下面一些问题:
- 主从同步很可能被破坏(现有全量同步机制需要重新改写)
- 重启时加载数据的机制.
- 不能支持全部命令, 容易造成混淆.
- 不能被主流所接受
如果不基于redis代码来做:
- 主从同步需要重做
- sentinel机制需要重做.
4.2 单机存储引擎
4.2.1 LevelDB
LevelDB是BigTable的单机存储, LSM-Tree 思想, 写操作都转化为顺序写.
特点:
KV引擎
支持SCAN(iteration)
Snappy压缩
- 随机读写能达到 10w/s 的性能
- 这里性能是小数据量下, 还不刷盘的情况
- 实际写能到10w, 读取决于存储介质.
支持Bloom Filter, 能在一定程度上优化读性能.
4.2.2 RocksDB(facebook)
- 基于LevelDB改进
- 更好的利用多核等
- 代码包比LevelDB复杂.
4.2.3 Berkley DB
历史悠久的嵌入式数据库
支持事务, 细粒度锁.
- 支持多种算法
- B+树
- Hash
- Heap(更节约空间)
- Recno
- Queue(定长record)
对一些老的UNIX数据库, 如dbm, ndbm接口兼容.
http://docs.oracle.com/cd/E17076_02/html/programmer_reference/am_conf.html
4.2.4 nessDB(国人开发)
支持事务 特点
- 自己实现存储引擎, 不是基于LevelDB
- 3.0 提供 Buffered-Tree index (Toku的FT-Tree)
- 作者是TokuDB的贡献者.
2011-2014持续开发, 目测代码质量很高.
本身是一个库.
- 还提供一个服务端,支持Redis的 PING, SET, MSET, GET, MGET, DEL, EXISTS, INFO, SHUTDOWN 命令,
- 现在已经专注于实现引擎, 不提供server功能了.
整个引擎基于LSM-Tree思想开发,对随机写非常友好。为提高随机读,nessDB使用了Level LRU和Bloom Filter策略。
引擎是自己开发的, 还需要时间验证.
4.2.5 小结
- 较老的存储引擎都基于B+树或Hash实现, 写性能差.
- 较新的存储引擎基于LSM-Tree, Log Structed Hash, FT-Tree之类新的数据结构, 针对写进行优化, 写性能能得到很大改善
- 读操作主要取决于底层磁盘能提供的 随机读IOPS , 通过Bloom Filter等能有一定的优化.
4.3 备选项目
4.3.1 ssdb
ssdb 是一个基于leveldb的kv存储, 提供兼容redis的协议
支持String, Hash, Zset, Queue几种数据结构.
支持Expire和主从同步
ssd上写性能稳定在3.8wqps, 不会随着写数据增多而变差, 和hdd差不多,
读性能稳定在5000qps, 不能充分发挥硬件性能, 这主要是由于读操作是单线程顺序执行.
- 主要问题:
- 读性能问题(多线程可达到15000)
- 所有expire的key记录在内存
- 兼容问题(expire/ttl/del都有问题, scan类设计上和redis不同)
详细参考:
- SSDB代码阅读笔记
- SSDB benchmark
4.3.2 fatcache
Memcache on SSD
Log-Structure Hash结构.
不能持久化(元数据不落盘, 重启后数据丢失)
性能不错, Initial performance results with fatcache 100K sets/sec, 40K gets/sec on a single SSD
读不命中时效率高(所有key记录在内存中)
写裸盘. 需要root.
- 主要问题:
不持久化
- key都放在内存, 如果10亿条的话, 每条key 32字节, 就需要32G. 此时存的数据(100字节/kv) 大约100G.
- 所以这适合value较大的情况, 比如1K, 这样32G内存就能管理1T数据.
详细参考: fatcache代码阅读笔记
4.3.3 ardb
https://github.com/yinqiwen/ardb
- Full redis-protocol compatible
- Most redis commands supported, and a few new commands
- Replication compatible with Redis 2.6/2.8
- Auto failover support by redis-sentinel
- 存储引擎支持 LevelDB/LMDB/RocksDB
- 空间索引.
- 代码量5w, 很难想象是一个人的作品. (HUST)
看上去很不错, c++实现.
4.3.4 ledisdb
- go 实现(金山 siddontang)
- https://github.com/siddontang/ledisdb
- 支持多种引擎: LevelDB, goleveldb, LMDB, RocksDB, BoltDB.
- 支持expiration
- 比GoRedis完善
- 写的很细心
- lua
- redis 协议 +rest协议
设计:
- http://siddontang.com/2014/05/10/ledisdb-introduction/
- http://siddontang.com/2014/05/30/ledisdb-design-1/
- http://siddontang.com/2014/06/14/ledisdb-design-2/
4.3.5 其它
- memcachedb
- https://gitorious.org/mdb/memcachedb/source/9f2e5415e4d9017889caf61c100a9b8652825319
- redis-leveldb
- 不是基于redis的代码,
- https://github.com/KDr2/redis-leveldb
- redis-protocol compatible
- libev, cpp实现.
- 2000行代码, 简单实现的玩具, 代码中各种printf直接输出到终端. 代码质量差
- 没有expire, 主从同步,
- seqdb
- 提供sql接口的kv.
- GoRedis
- go实现, (陌陌)
- 存储引擎使用RocksDB, redis接口.
- 不支持expire
- slaveof-proxy为两个redis建立自定义的主从同步,包含限速、断线重试等。
- rdisk 是一个hackathon项目, 提供兼容redis的协议.
- libuv做服务
- rangel 解析
- tokyocabinet 作为存储引擎(作为.so嵌入)
- https://github.com/Moodstocks/redisk
- 是一个不错的开始
- lycadb
- An experiment with InnoDB storage for a Redis-like key/value store
- redis-land-go
- https://github.com/xjdrew/redis-land-go
- 旁路监听,把redis数据存盘到leveldb
4.3.6 小结
- 有很多尝试做兼容redis的磁盘存储的项目,
- 在设计实现上都存在或多或少的问题.
4.4 成熟分布式存储系统
4.4.1 淘宝tair
淘宝开发的分布式 key/value 存储系统
- 模块
- config-server (master+slave)
- data server (存储节点)
- 客户端保存路由表, 有local cache
- 一致性hash+数据迁移
- 存储引擎
- mdb: 缓存, 支持kv,
- rdb: redis内存结构, kv, list, set, zset.
- ldb: 基于leveldb.
需要专用的 client lib.
支持多副本, 多版本.
- 规模(2011):
- 共有20多个集群,400多台的服务器,其中300多台是cache的,每台提供22G的内存。其他的是持久化的Tair集群。
- 存放了数百亿条记录,每秒百万级别的请求数。
http://code.taobao.org/p/tair/wiki/intro/
4.4.2 aerospike
商业产品, 开源.
- 三层:
- client 感知数据存在哪里
- Distribution Layer
- Data Storage Layer: 单机引擎.
API形式: 不是简单的key/value, 每个key需要指定 (namespace, set, key), 应该是为了控制锁粒度.
Indexes are always stored in RAM.
数据类型: map, list, integer, string, blob.
可配 expire
支持lua.
支持Secondary indexes, 不是简单kv, 更像mongo
支持Hot Analytics (distributed aggregations or indexed map-reduce)
https://github.com/aerospike/aerospike-server
4.4.3 #facebook Apollo
http://www.infoq.com/news/2014/06/facebook-apollo
- Paxos-like NoSQL database
- C++
- 低延迟, 特别是Flash and in-memory
- 不是简单kv, 支持数据结构: maps, queues, trees
- 分布式, 有shard概念, 每个shard内基于RocksDB.
- Apollo isn't currently being used in production at Facebook
- The company is also looking at using Apollo as a reliable queuing system
- 是分布式的ssdb
- 还没开源.
4.4.4 #facebook-McDipper
https://www.facebook.com/notes/facebook-engineering/mcdipper-a-key-value-cache-for-flash-storage/10151347090423920
Compared with memory, flash provides up to 20 times the capacity per server and still supports tens of thousands of operations per second,
- 大约12年5月上线.
- cache替换策略: LRU或者FIFO
- you can enable bloom filters to avoid unnecessary reads
- 主要用于图片服务器的缓存(cdn上) 后端是HayStack.
- We serve over 150 Gb/s from McDipper forward caches in our CDN.
- 是一个cdn用的cache存储. memcache协议.
- 不开源.
4.4.5 #腾讯CKV海量分布式存储系统
(闭源, 这里参考一个ppt)
http://www.csdn.net/article/2014-03-11/2818723
高性能、低延时、持久化、分布式KV存储服务, 日请求数: 超过万亿次 (那得看多少套集群)
与Memcached和Redis等开源NoSQL相比,CKV具有以下优点.
内存+SSD, 99%命中率(取决于应用)
可以扩展到1PB
单表 千万qps
单台Cache服务器千兆网络环境支持50万/秒的访问,万兆网络环境支持超过100万/秒的访问 <redis也10个实例, 也可以做到>
双机热备,主备切换对业务透明. redis一样.
- 扩容: 需要停写
- 扩容过程如下:Master将禁止shard2数据写访问命令发送给Access
- 规模: 近万台服务器
- 万台, 每天万亿请求, 那就是说1亿/台, 每台只相当于1000qps.
4.4.6 小结
- 这里的几个系统, 都是类似GFS的架构, config-server + data server + 智能client
- 支持动态数据迁移和路由更新.
- 它们都有各自的接口, 相对来说比较复杂.
4.5 其它思路
- HBase/Cassendra/MySQL on ssd?
- 可以利用现有hbase等系统良好的扩展性, 性能上也能有所保证
- 接口不兼容.
- 过于复杂.
5 小结
- 为了避免随机写, 现在很多存储引擎都是Write-optimized的, 基于LSM的思想来开发, 比如:
- fatcache/Riak: Log-Structure Hash table
- RethinkDB: Log-Structure B-tree
- LevelDB, Cassendra, HBase: Log-Structure merge tree.
LevelDB 平均每次读大约需要1.3-1.5次IO, Log-Structure Hash 只需要1次, 但是不能scan.
ssdb/ardb/nessDB/ledisdb 都是国人做的, 很赞, 值得持续关注.
可以否决基于redis做的改造.
基于LevelDB或者RocksDB封装提供redis协议比较简单, 难点主要是expire/replication/failover的实现.
5.1 关于目前的很多系统
无论对redis改造或者是重新实现, 在数据结构/expire/主从同步上, 都延用了redis的做法, 比如:
支持富数据结构
expire信息放在内存
主从断掉全量同步.
- 依然有rdb, 整个库占了1T磁盘, rdb出来也占1T => 这些设计可能没考虑1T这个数据量级, 只考虑100G这个量级.
- 比如ardb依然使用rdb做同步.
甚至有的还会把磁盘操作计入aof, 再加上aof_rewrite,
由于数据规模变大(60G=>600G的级别) 这些设计就存在问题.
- 存储:
- 同步: ?
- 切换: ?
- 存储: 自定义binlog,fid+offset
- 同步: 从拉,全量+增量
- 切换: 全量同步
- ssd-cache
- ssd-cache 不错的kv系统总结
- 使用dm-cache,将SSD用作HDD的Cache
- ssd
- SSD
- SSD
- ssd
- SSD
- SSD
- ssd
- SSD
- ssd
- SSD
- SSD
- ssd
- [转]Linux块设备加速缓存bcache和dm-cache:使用SSD来加速服务器
- MYSQL高性能IO之日志裸设备+数据裸设备+SSD cache
- cache
- Velocity和FreeMarker - Spring Framework reference 2.0.5 参考手册中文版
- 【postman】中 form-data、x-www-form-urlencoded、raw、binary的区别
- 集中式vs分布式
- Android之 AudioTrack学习
- javaweb学习总结(三十六)——使用JDBC进行批处理
- ssd-cache
- Java的while、for循环
- Android EditText得到和失去焦点、内容变化的监听
- 长轮询和轮询
- EasyUI 组合
- 恒星演化 —— 恒星的一生
- javaweb学习总结(三十七)——获得MySQL数据库自动生成的主键
- 这样 好吗?
- 机器学习面试问题8