最近有个业务写远远大于读,读也集中在最近写入,这不很适合采用leveldb存储么,leveldb业界貌似ssdb用得挺广,花了两天时间就ssdb简单做下测试,以下总结。

  ssdb 是leveldb的redis兼容协议封装,并且实现了主从同步,源码不多易读;主要对redis命令封装,get/set 不说,leveldb 是有序的,相比redis通过scan遍历的命令,利用有序性 list、hset也通过key+fileld/seq - val 方式存储,ttl 会单独存储一个hset 保存过期时间,由一个单独线程定时轮询删除。

  leveldb 参考:  

  http://www.cnblogs.com/haippy/archive/2011/12/04/2276064.html

  http://blog.csdn.net/houzengjiang/article/details/7718548

测试场景

机器:两台R720XD E5-2620 2.1G (6核12线程)*2/内存128GB/300GB机械硬盘
数据: key: key 10位顺序数字 value: 50字节
并发: 默认情况100连接并发
客户端: 使用erlang erdis模块get/set
 
配置:
leveldb:
        cache_size: 500
        block_size: 1
        write_buffer_size: 64
        compression: no
        max_open_files: 1000
  

数据量:2kw

- 文件大小:1.3GB
- 写速度:7w/s  CPU 250%  mem:30M
- 随机读: 5.5w/s  CPU  100%  mem:1GB
- 并发读写1:10: 读 5k/s 写:5w/s,CPU 250%
总结:总体性能和github给出的相近;leveldb数据存放十分紧凑,因为会对key开启前缀压缩,如果开启snappy后会更小,即使全量缓存到内存,内存消耗也会比redis 少很多。
 

数据量:1.5亿

- 文件大小:9.6GB
- 写速度:7w/s  cpu: 250%  mem:70M
- 随机读:  1.6w/s cpu:100% mem:70M
-并发读写:1: 10: 4k/s 读  5w/s 写 250%
总结:读太随机的LRU cache 无法有效缓存任何数据,请求都要经过文件系统读取,性能下降;但写保性能持不变
 

数据量:10亿

- 文件大小:66GB
- 写速度:7w/s  cpu:250% mem:80M
- 随机读:  1.6w/s cpu:180% mem:80M
-并发读写:1: 10: 4k/s 读:5w/s 写:280%
总结:和1.5亿级别效果保持一致
 

page cache

     leveldb默认缓存meta data、和8M的block;本次测试使用了500M block_cache,从测试效果看,因为随机读,cache只在2k数据级别上起到作用,且带来很高性能提升。
     1.5亿、10亿时,完全依赖kernel 对文件系统的page cache,机器有128GB内存,leveldb 没有使用direct io,文件都缓存,实际运行中不会有磁盘IO。
     那么使用脚本清理:     
     while true;  do echo 1 > /proc/sys/vm/drop_caches;echo clean cache ok; sleep 1; done
 
- 随机读 约160/s  cpu: 5%  mem: 120m  iostat 95%util
- 1并发随机读,100并发写:90/s 读, 1500/s 写,随机读取影响写入速度
总结:
     随机IO在机械硬盘上是完全无解了,只能靠cache扛,相比page cache,block_cache 更有效,应该更加需求增加bock_cache。
     相比增加内存,使用ssd硬盘成本更低。
 
读取系统调用:
open("./var/data/006090.ldb", O_RDONLY) = 27

stat("./var/data/006090.ldb", {st_mode=S_IFREG|0644, st_size=34349641, ...}) = 0
mmap(NULL, 34349641, PROT_READ, MAP_SHARED, 27, 0) = 0x7f0334f76000
madvise(0x7f040457e000, 737280, MADV_DONTNEED) = 0
munmap(0x7f03dc2ab000, 34349599)        = 0
close(27)                               = 0
 

多线程

ssdb 是多线程的,但上面测试效果看有明显多核利用率很低问题,从源码看可以知道:
- 1个主线程,负责网络io
- 10个读线程,负责像scan复杂操作读
- 1个写线程,负责写操作磁盘io
- 1个leveldb 的compact线程
 
     也就是写set 一个主线程负责网络,一个写线程负责leveldb操作;而读get 只有主线程在工作。
 
ssdb相关都没有配置,简单修改源码重新编译:
 
- 10个线程处理读:2.5/s  CPU 450%
     60%消耗在sys,高并发读文件对内核瓶颈
- 减小至3个线程处理读:3.2w/s 280%(相比10线程,更少的CPU消耗,更高的性能)
- 使用LRUCahce 在1kw区间随机读  7w/s ,200%CPU

可靠性

     leveldb 更新前先写日志方式,但默认方式日志mmap是不会做msync,也就是完全依赖操作系统刷磁盘,这样存在机器掉电等意外故障时可能会丢失部分最新消息。支持leveldb:WriteOptions.sync可选参数,但ssdb默认false,改为需要修改代码。
     修改true后,奇怪性能无变化?代码上看并不是每个写都会msync,而是4kbuffer后刷一次。
     那么leveldb 在故障时可能丢时少量数量就是没办法的了,如需要强可靠需要注意。
 
     测测msync速度怎么样呢?
     简单单线程c程序,每写100字节做一次msync,效果:
     服务器2w/s, 我的mac pro ssd 3w/s (此时ssd也没太大优势)
 
     msync 每次都做的话,肯定是有较大的性能影响的,但是可以做group msync;group  msync 会增加延时,就看可接受都少了,如0.1ms,那就就可以以1w/s 脉冲式,批量sync磁盘,保证所有请求都写入磁盘再返回。
 

batch

     leveldb 的写入、修改、删除都是支持优化的batch操作,使用multi_set命令。
 

最佳实战

1. 写性能
     测试中,写入速度一直维持7w/s, 可满足到多需求, leveldb 写入可以到40w/s, 这里受限于ssdb 线程模型无法利用更多的核心。需要的话通过pipline、网卡中断平衡、提高网络、leveldb写线程数 来提高写入性能。
2. 读性能
     一般业务都存在数据热点,可调整cache_size, block_size 提高缓存命中率,block_size 为缓存块大小1K~4M视具体业务value而定。
     如果业务热点度不高,那只能上ssd硬盘了。
     注意使用了page cache,不小心清空会让性能急剧下降,还是尽量配置足够大的cache_size。还有就是启动有个预热过程。
3. compaction
     本次使用的顺序key写入,因为业务上key 都是顺序的,然后一段时间从后往前顺序删除。compaction影响会很小,如果业务大量随机key写入、修改、删除会增加compaction量,需要注意。
 
 

leveldb 性能、使用场景评估的更多相关文章

  1. leveldb(ssdb)性能、使用场景评估

    最近有个业务场景存储压力很大,写远远大于读,读也集中在最近写入,想想这不很适合采用leveldb存储么.leveldb的话好像用ssdb比较多,花了两天时间就ssdb简单做下测试,以下总结. ssdb ...

  2. 使用jmeter对ActiveMQ集群性能方案进行评估--转载

    原文地址:http://www.51testing.com/html/78/23978-143163.html 1.测试概要1.1 关于这篇文档中涉及的基于JMS的消息系统能为应用程序提供可靠的,高性 ...

  3. rocksdb和leveldb性能比较——写性能

    前面学习了一下rocksdb,这个db是对leveldb的一个改进,是基于leveldb1.5的版本上的改进,而且leveldb1.5以后也在不断的优化,下面从写入性能对两者进行对比. 前言 比较的l ...

  4. leveldb性能分析

    Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了. 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计.特别是LSM算法. 那 ...

  5. loadrunner11的移动端性能测试之场景设计

    测试步骤之场景设计(Controller) 进入手工场景 准备好脚本后就可以进行场景设计和执行场景了,从VuGen中进入,见下图: 进入后第一个为目标场景,选择第二个更灵活的手工场景,我的目标人数20 ...

  6. mysql 性能容量评估

    性能容量评估   分析上线业务场景 评估数据库服务器所需性能指标 预估可能成为瓶颈的服务器资源 帮助数据库性能调优   数据库服务器硬件性能指标项: 磁盘IO性能 内存容量 CPU 网络吞吐量 磁盘容 ...

  7. Coursera Machine Learning : Regression 评估性能

    评估性能 评估损失 1.Training Error 首先要通过数据来训练模型,选取数据中的一部分作为训练数据. 损失函数可以使用绝对值误差或者平方误差等方法来计算,这里使用平方误差的方法,即: (y ...

  8. 【机器学习与R语言】12- 如何评估模型的性能?

    目录 1.评估分类方法的性能 1.1 混淆矩阵 1.2 其他评价指标 1)Kappa统计量 2)灵敏度与特异性 3)精确度与回溯精确度 4)F度量 1.3 性能权衡可视化(ROC曲线) 2.评估未来的 ...

  9. [AlwaysOn Availability Groups]监控AG性能

    监控AG性能 AG的性能的性能方面,在关键任务数据库上进行语句级维护性能是很重要的.理解AG如何传输日志到secondary副本对评估RTO和RPO,表明AG是否性能不好. 1. 数据同步步骤 为了评 ...

随机推荐

  1. 写出将字符串中的数字转换为整型的方法,如:“as31d2v”->312,并写出相应的单元测试,正则去掉非数值、小数点及正负号外的字符串

    写出将字符串中的数字转换为整型的方法,如:"as31d2v"->312,并写出相应的单元测试,输入超过int范围时提示不合法输入. public struct Convert ...

  2. ViewPager实现引导页

    1. 要使用ViewPager,必须要创建 PagerAdapter. 这里创建一个 ViewPagerAdapter来继承PagerAdapter public class ViewPagerAda ...

  3. SQL基础语法(二)

    SQL SELECT 语句 本章讲解 SELECT 和 SELECT * 语句. SQL SELECT 语句 SELECT 语句用于从表中选取数据. 结果被存储在一个结果表中(称为结果集). SQL ...

  4. 递推 hdu 1330

    http://www.cnblogs.com/rainydays/archive/2013/01/16/2862235.html 看样例的答案 #include<stdio.h> #inc ...

  5. com.panie 项目开发随笔_前后端框架考虑(2016.12.8)

    (一) 近日和一同学联系,说了我想要做一个网站的打算.她很感兴趣.于是我们协商了下,便觉得一起合作.她写前端,我写后台.因为我对于前端样式设计并不怎么熟悉. (二) 我们决定先做一个 个人博客. 网上 ...

  6. substr()函数

    substr 定义于头文件 <string> string substr (size_t pos = 0, size_t len = npos) const;复制子字符串,要求从指定位置开 ...

  7. iOS - 消息转发处理

    详细运行时基础 NSInvocation介绍 NSHipster-Swizzling Objective-C Method相关方法分析 Type Encodings Objc是OOP,所以有多态. 当 ...

  8. TableView 滑动收起键盘

    self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; 拖拽tableView就会收起键盘

  9. Linux在fstab中因配置错误导致服务器主机无法重启的问题应该如何解决

    fstab中配置错误导致系统无法启动的恢复方案 1制造错误的案例发生,在/etc/fstab中配置如下内容 结尾的倒数第一个为1表示进行磁盘检查,为0表示不进行磁盘检查,倒数第二个为0表示不备份,为1 ...

  10. Oracle 的字符集与乱码

    字符集问题一直叫人头疼,究其原因还是不能完全明白其运作原理. 在整个运行环节中,字符集在3个环节中发挥作用: 1.软件在操作系统上运作时的对用户的显示,此时采用操作系统定义的字符集进行显示.我们在系统 ...