Table of Contents
其它:
主要涉及下面几个方面:
本文是这个调研系列的目录和结论, 相关调研:
-- | 国外 | 国内 | 2T成本 |
---|---|---|---|
ssd | $0.6/GB | 京东价格(400元/128G=3.1元/GB) | 6000 |
hdd: | $0.12/GB | 京东价格(400元/1T=0.4元/GB) | 800 |
目前ssd主要2种接口:
sata
sata 带宽6Gbps, pci-e 常见带宽 3.2G*8 = 24Gbps.
Product | Intel SSD 320 | Intel SSD 530 | ioMemory PX600 |
---|---|---|---|
Components | MLC | MLC | MLC |
Launch Date | 2011 | 2013 | |
Sequential Read | 270 MB/s | 540 MB/s | 2700 MB/s |
Sequential Write | 220 MB/s | 490 MB/s | 1500MB/s |
Random Read (8GB Span) | 39,500 IOPS | 48,000 IOPS | 196,000 IOPS |
Random Write (8GB Span) | 23,000 IOPS | 80,000 IOPS | 320,000 IOPS |
Latency - Read | 75 us | 80 us | 92 us |
Latency - Write | 90 us | 80 us | 15 us |
interface | SATA 6.0 Gb/s | SATA 6.0 Gb/s | PCI-Express 2.0 x8 |
数据来源:
notes:
这里选的 Fusion-io ioMemory系列, 写可以达到32w/s, 写延迟只有15us, 很明显写操作都是先写buffer.
随机读性能好
写放大: 写一个字节也会导致整个page的read-modify-write
应该尽量避免small-write
顺序读写和hdd在同一量级.
寿命有限
ssd可以通过下面这些方式调优:
详细参考: coding-for-ssd笔记
针对我们的需求, 调研了一些现有的系统, 主要分三类:
redis在2.2-2.4曾经做过vm功能, 来将内存扩展到磁盘, 但是不久就被废弃了, 原因主要是造成性能不稳定.
存在的问题:
作者的观点:
把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很诡异.
没有expire支持, leveldb过大后, 怎么办?
完全没有考虑到主从的设计.
参考:
基于redis的改进, 主要有这么几种:
如果基于redis来实现, 存在下面一些问题:
如果不基于redis代码来做:
LevelDB是BigTable的单机存储, LSM-Tree 思想, 写操作都转化为顺序写.
特点:
KV引擎
支持SCAN(iteration)
Snappy压缩
支持Bloom Filter, 能在一定程度上优化读性能.
历史悠久的嵌入式数据库
支持事务, 细粒度锁.
对一些老的UNIX数据库, 如dbm, ndbm接口兼容.
http://docs.oracle.com/cd/E17076_02/html/programmer_reference/am_conf.html
支持事务 特点
2011-2014持续开发, 目测代码质量很高.
本身是一个库.
整个引擎基于LSM-Tree思想开发,对随机写非常友好。为提高随机读,nessDB使用了Level LRU和Bloom Filter策略。
引擎是自己开发的, 还需要时间验证.
ssdb 是一个基于leveldb的kv存储, 提供兼容redis的协议
支持String, Hash, Zset, Queue几种数据结构.
支持Expire和主从同步
ssd上写性能稳定在3.8wqps, 不会随着写数据增多而变差, 和hdd差不多,
读性能稳定在5000qps, 不能充分发挥硬件性能, 这主要是由于读操作是单线程顺序执行.
详细参考:
Memcache on SSD
Log-Structure Hash结构.
不能持久化(元数据不落盘, 重启后数据丢失)
性能不错, Initial performance results with fatcache 100K sets/sec, 40K gets/sec on a single SSD
读不命中时效率高(所有key记录在内存中)
写裸盘. 需要root.
不持久化
详细参考: fatcache代码阅读笔记
https://github.com/yinqiwen/ardb
看上去很不错, c++实现.
设计:
淘宝开发的分布式 key/value 存储系统
需要专用的 client lib.
支持多副本, 多版本.
商业产品, 开源.
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)
http://www.infoq.com/news/2014/06/facebook-apollo
Compared with memory, flash provides up to 20 times the capacity per server and still supports tens of thousands of operations per second,
(闭源, 这里参考一个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一样.
LevelDB 平均每次读大约需要1.3-1.5次IO, Log-Structure Hash 只需要1次, 但是不能scan.
ssdb/ardb/nessDB/ledisdb 都是国人做的, 很赞, 值得持续关注.
可以否决基于redis做的改造.
基于LevelDB或者RocksDB封装提供redis协议比较简单, 难点主要是expire/replication/failover的实现.
无论对redis改造或者是重新实现, 在数据结构/expire/主从同步上, 都延用了redis的做法, 比如:
支持富数据结构
expire信息放在内存
主从断掉全量同步.
甚至有的还会把磁盘操作计入aof, 再加上aof_rewrite,
由于数据规模变大(60G=>600G的级别) 这些设计就存在问题.
代码 | 特点 | expire | repl | 其它 | ||
---|---|---|---|---|---|---|
2 | redis-storage | redis+特定命令 | 无 | 无 | 专注于使内存成为磁盘的cache | |
3 | ssdb | 单独key存储 | ||||
3 | ardb | 5w | cpp, 复杂, 地理索引 |
|
兼容性好, 沿用redis, 依然支持rdb | |
3 | ledisdb(go) 金山 | 2w | 单独key存储, 定期elim |
|
||
2 | GoRedis | 2w |