免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: wlmqgzm
打印 上一主题 下一主题

[C++] 读性能超过Memcached 65%, 单核也超过redis, 支持日志支持掉电保护,欢迎试用 [复制链接]

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
131 [报告]
发表于 2017-03-10 21:13 |只看该作者
本帖最后由 wlmqgzm 于 2017-03-28 16:36 编辑

目前版本1.0.35  查询性能已经比memcache大约高出64%,
插入/更新性能比memcache高出30%,
由于Redis只支持单CPU线程, 我们的软件支持多CPU线程,因此, 我们的性能在多核CPU下比Redis快得多.
优化后的新版本性能又提高了一些,

1)测试方法:
运行 memcached, 需要指定8192M内存, 以便可以测试百万以上的数据量, 指定端口号是1983
memcached -m 8192 -p 1983

我们的程序是动态申请内存, 因此, 不需要指定预先分配的内存量, 直接运行就可以了
haisql_memcache_chinese
我们的软件默认运行端口是1971

每次测试后需要清理运行环境, memcached直接ctrl_C退出就可以了.
我们的软件因为退出时默认自动保存内存数据, 因此,需要在退出程序后,执行 rm *.txt;sync;sync 清理掉自动保存的数据, 相当于清空全部数据,这样下次启动时就是空数据表了.

2)测试情况:
先测试 读性能 测试软件自动写入1万条记录, 然后测试读取900万次, 我们的软件执行时间是23.631秒, memcache执行时间是38.828秒, 我们的软件比memcache快64%
我们的软件读性能如下: 读4.1Kbyte的数据包大小, 4核8线程3.4G主频DDR3内存, 读900万次数据, 900并发, 花费时间 23.631秒, 读性能38万QPS.

第1次是memcached的测试结果, 第2次是我们的软件测试结果
guo@guo-desktop:~$ memcslap --concurrency=900  --servers=127.0.0.1:1983 --test=get
    Threads connecting to servers 900
    Took 38.828 seconds to read data

guo@guo-desktop:~$ memcslap --concurrency=900  --servers=127.0.0.1:1971 --test=get
    Threads connecting to servers 900
    Took 23.631 seconds to read data

测试 写性能 测试软件测试写入100万条记录, 我们的软件执行时间是3.136秒, memcache执行时间是4.078秒, 我们的软件比memcache快30%
我们的软件写性能如下: 写4.1Kbyte的数据包大小, 4核8线程3.4G主频DDR3内存, 写100万次数据, 100并发, 花费时间3.136秒, 写性能32万TPS.

第1次是memcached的测试结果, 第2次是我们的软件测试结果
guo@guo-desktop:~$ memcslap --concurrency=100  --servers=127.0.0.1:1983
    Threads connecting to servers 100
    Took 4.078 seconds to load data

guo@guo-desktop:~$ memcslap --concurrency=100  --servers=127.0.0.1:1971
    Threads connecting to servers 100
    Took 3.136 seconds to load data

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
132 [报告]
发表于 2017-03-13 12:52 |只看该作者
我们目前的haisql_memcache数据库查询性能已经超越memcache37%,更新插入性能超越21%,还是动态申请内存的,网络层还是用Boost Asio这种封装了多层,为了满足兼容全部操作系统冗余代码很多的,说明了即使是KV数据库这种已经非常成熟的产品上,只要有新思路, 性能还是可以大幅度提升。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
133 [报告]
发表于 2017-03-13 16:30 |只看该作者
本帖最后由 wlmqgzm 于 2017-03-13 16:51 编辑

linux的socket 在内部使用了文件句柄来获取操作系统资源,因此,如果需要同时并发100万个连接,需要设置
最大打开文件句柄数为101万,才能进行测试和使用。

在/etc/security/limits.conf文件中设置最大打开文件句柄数,
添加如下这2行
* soft nofile 1010000
* hard nofile 1010000   

执行 ulimit -n  指令可以显示目前系统限制 最大打开文件句柄数,例如:
ulimit -n
65535

论坛徽章:
3
处女座
日期:2015-03-18 14:35:45羊年新春福章
日期:2015-03-18 14:48:23午马
日期:2015-03-18 14:51:09
134 [报告]
发表于 2017-03-17 14:14 |只看该作者
回复 112# wlmqgzm

呵呵

论坛徽章:
0
135 [报告]
发表于 2017-03-21 14:36 |只看该作者
master slave 的问题 这么简单就说解决了,说起来简单,那么paxos 这么复杂 就是白搞了,完全是门外汉在自娱自乐!

memcached 的速度 不是最关键的,至于你说的37%, 也是需要大量的测试用例 来均衡测的, 各种key 各种value 组合才能确定 是不是这样。


其实redis 是单线程的,但是完全可以多redis 合并, 外部用一个hash路由,那个性能 比你这个服务器 再比比。
其次redis 的单线程的, 如果都是单线程的客户端压力,比一比 你就知道 到底谁强了。


论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
136 [报告]
发表于 2017-03-28 15:59 |只看该作者
本帖最后由 wlmqgzm 于 2017-03-28 16:34 编辑

最近一个月时间都在处理某个多线程项目的幽灵般的BUG,  飘忽不定,时有时无,各种无厘头。。。。。。。。2周多时间
终于最后定位到A//B/C/D.......线程申请的大量std::shared_ptr<std:;string>, Z线程乱序处理后自动释放,在某些偶然的情况下,会出现内存整体混乱。
最终的解决办法是做了一个中间cache层,负责跨线程的内存回收,A线程申请,然后托管std::shared_ptr<std:;string>到中间cache层,cache层会自动处理无效数据, 最终实现还是A线程释放,
直白说就是谁申请的内存,谁负责释放,问题得到了解决。


目前版本的 Haisql_memcache 新功能方面没有新增,但是性能优化后,有不少提高,版本号1.0.35
主要是优化了内存分配机制,对于最常见的变量std::string,std::shared_ptr<std:;string>等等都定义了自己的更高效率的内置资源池,实现更好的内存分配器和内存回收机制,
第2个就是将各变量组合排列,将同时变化的放到一起,提高CPU cacheline的效率,
第3个就是将网络层boost asio中的函数尽量使用更接近底层的调用函数receive/send等,减少调用的层次等等办法

目前查询性能已经比 memcached 原生版本高64%,测试方法和测试软件都是官方的 memcslap( ubuntu自带安装包 )
本机测试的时候,打开 top 可以明显看到服务器软件 haisql_memcache 比测试软件memcslap消耗的CPU资源小得多,说明了服务器端代码的效率确实是非常高。

测试方法:
1) 运行 memcached, 需要指定8192M内存, 以便可以测试百万以上的数据量, 指定端口号是1983
memcached -m 8192 -p 1983

我们的程序是动态申请内存, 因此, 不需要指定预先分配的内存量, 直接运行就可以了
haisql_memcache_chinese
我们的软件默认运行端口是1971

每次测试后需要清理运行环境, memcached直接ctrl_C退出就可以了.
我们的软件因为退出时默认自动保存内存数据, 因此,需要在退出程序后,执行 rm *.txt;sync;sync 清理掉自动保存的数据, 相当于清空全部数据,这样下次启动时就是空数据表了.

测试情况:
先测试 读性能 测试软件自动写入1万条记录, 然后测试读取900万次, 我们的软件执行时间是23.631秒, memcache执行时间是38.828秒, 我们的软件比memcache快64%
我们的软件读性能如下: 读4.1Kbyte的数据包大小, 4核8线程3.4G主频DDR3内存, 读900万次数据, 900并发, 花费时间 23.631秒, 读性能38万QPS.

第1次是memcached的测试结果, 第2次是我们的软件测试结果
guo@guo-desktop:~$ memcslap --concurrency=900  --servers=127.0.0.1:1983 --test=get
    Threads connecting to servers 900
    Took 38.828 seconds to read data

guo@guo-desktop:~$ memcslap --concurrency=900  --servers=127.0.0.1:1971 --test=get
    Threads connecting to servers 900
    Took 23.631 seconds to read data

测试 写性能 测试软件测试写入100万条记录, 我们的软件执行时间是3.136秒, memcache执行时间是4.078秒, 我们的软件比memcache快30%
我们的软件写性能如下: 写4.1Kbyte的数据包大小, 4核8线程3.4G主频DDR3内存, 写100万次数据, 100并发, 花费时间3.136秒, 写性能32万TPS.

第1次是memcached的测试结果, 第2次是我们的软件测试结果
guo@guo-desktop:~$ memcslap --concurrency=100  --servers=127.0.0.1:1983
    Threads connecting to servers 100
    Took 4.078 seconds to load data

guo@guo-desktop:~$ memcslap --concurrency=100  --servers=127.0.0.1:1971
    Threads connecting to servers 100
    Took 3.136 seconds to load data

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
137 [报告]
发表于 2017-03-28 17:08 |只看该作者
回复 136# benjiamsh

专门找了一台双核的机器,Intel(R) Pentium(R) CPU G3258 @ 3.20GHz
本机127.0.0.1测试,  相当于一个CPU用于测试,一个CPU用于服务器, 以便测试对比一下与Redis的单核性能对比。

单核查询性能还是比redis更快, 先插入10000条记录,900连接,每连接10000次查询,总共测试900万次查询,每次查询value包大小4096字节
redis花费
93.46秒, 我们的软件花费63.792秒, 测试方法都是官方的测试软件,我们的单核性能比redis的单核性能快 46.5%,

测试情况如下:

guo@guo-desktop2:~$ redis-cli
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> quit
guo@guo-desktop2:~$
guo@guo-desktop2:~$
guo@guo-desktop2:~$ redis-benchmark -t set -n 10000 -r 10000 -d 4096 -c 100
====== SET ======
  10000 requests completed in 0.08 seconds
  100 parallel clients
  4096 bytes payload
  keep alive: 1

91.61% <= 1 milliseconds
99.99% <= 2 milliseconds
100.00% <= 2 milliseconds
125000.00 requests per second


guo@guo-desktop2:~$ redis-benchmark -t get -n 9000000 -r 10000 -d 4096 -c 900
====== GET ======
  9000000 requests completed in 93.46 seconds
  900 parallel clients
  4096 bytes payload
  keep alive: 1

0.00% <= 4 milliseconds
65.86% <= 5 milliseconds
72.01% <= 6 milliseconds
72.98% <= 7 milliseconds
73.56% <= 8 milliseconds
97.70% <= 9 milliseconds
99.45% <= 10 milliseconds
99.72% <= 11 milliseconds
99.80% <= 12 milliseconds
99.97% <= 13 milliseconds
100.00% <= 14 milliseconds
100.00% <= 14 milliseconds
96294.80 requests per second

guo@guo-desktop2:~$ memcslap --concurrency=900 --servers=127.0.0.1:1971 --test=get
    Threads connecting to servers 900
    Took 63.792 seconds to read data
guo@guo-desktop2:~$  

论坛徽章:
0
138 [报告]
发表于 2017-03-30 22:22 |只看该作者
别的不说,46岁转程序员入坑,这就得鼓掌!!!

给楼主点赞。

顺便一提:
楼主同志,  我强烈建议您将此中间件开源,并且强烈建议您加入轰轰烈烈的自由软件运动。

我相信,您得到的会比失去的多得多。

论坛徽章:
0
139 [报告]
发表于 2017-03-30 22:32 |只看该作者
我在很久以前也写过存储层的函数库。那个时候也不知道redis,mongodb这些,就是凭着感性认识写。

主要侧重于多版本模型,以实现高并发的读写。实现的软件也不是KV的,也不是关系型的,是基于 page的。在page上修改,就是修改数据页,然后提交数据页。
提交的一批数据页是事务的,事务可能失败,页上有选项,如果此页要避免“遗失更新”,就可能提交失败。提交失败,这次修改就不算了,要重来。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2015-10-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-01 06:20:00程序设计版块每日发帖之星
日期:2015-11-02 06:20:00每日论坛发贴之星
日期:2015-11-02 06:20:00程序设计版块每日发帖之星
日期:2015-11-03 06:20:00程序设计版块每日发帖之星
日期:2015-11-04 06:20:00程序设计版块每日发帖之星
日期:2015-11-06 06:20:00数据库技术版块每周发帖之星
日期:2015-12-02 15:02:47数据库技术版块每日发帖之星
日期:2015-12-08 06:20:00
140 [报告]
发表于 2017-04-13 20:21 |只看该作者
本帖最后由 wlmqgzm 于 2017-04-14 09:22 编辑

刚提交了1.0.36版本, 主要改进了各类锁的使用,提供更大的并发:

1)使用了读写锁(读 共享锁,写独占锁),替换掉了原来统一的spin_lock, 提高了读并发性,实现了多线程同时读有更大的并发性
2)改善了getg/ getl/ append/prepend/append/incr/decr的性能,比上个版本有不少提高。
3)改进了 所有修改命令的 锁机制,将锁划分为2层读写锁,第一层是全局锁,exec时是使用独占锁,保证事物处理的唯一性, 普通set/add/replace等修改命令是共享锁,用于保证事务处理的完整性。
第2层是数据层锁, 32张表,每表划分256组,一共8192把读写锁,get/gets等命令读数据时使用共享锁,set/add/replace等命令写数据时使用独占锁。可以保证查询数据无限并发,写数据时锁冲突的概率也非常低,因为一共有8K把锁,
而我们使用的线程数量是CPU数量X2, 对于8核CPU来说,同时运行的线程只有16个线程,16个线程竞争8192把锁,理论上几乎不会有写冲突。

目前查询部分的代码已经优化到极限了, 全部代码都是C++的, 并且底层网络库是层层封装的Boost ASIO的情况下,能够远远超越memcache/redis等产品, 确实是非常不容易的,
我们重写了太多的C/C++底层库,整个C/C++底层库代码长度已经超过1万行,我们做过测试C/C++底层库在没有使用新算法新功能的情况下, 重复写一遍毫无意义,也不会有任何性能上的提升,
我们查阅了近年来很多的底层库的算法资料,然后重新实现了C/C++中的一些老旧内容,最终我们的产品性能方面有了巨大的提高。

更新修改部分的代码目前还有不少的优化余地,主要是目前的跨线程的内存释放和分配new/delete还有很大的优化空间,虽然我们使用了jemalloc这样比较新型的内存库,号称已经比gcc自带的内存库快一倍,
但是我们依旧在努力做更好的自研 内存库,因为我们的查询部分使用了内部的单线程内存cache层,所以,已经把性能做到了极致,应用层的部分命令甚至会小于1微秒的处理时间,当然网络层的每组收发包的4-5微秒是逃不过的,
当然, 未来如果有时间的话, 会在RDMA方向和Intel DPDK方向投入更多的资源,最终将这里的4-5微秒压缩到1个微秒,目前,我们还不具备这样的底层库。

在跨线程的内存管理方面,我们目前暂时没有性能足够高的解决方案,如果能够有更好的解决方案,那么set/add/replace的等命令的性能会有大幅度提高,因为每条命令都有一次跨线程的内存申请和释放的操作,
目前 set/add/replace的性能比get查询的性能慢很多,今后改进的余地也比较大。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP