忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
楼主: 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
发表于 2017-07-10 14:43 |显示全部楼层
本帖最后由 wlmqgzm 于 2017-07-13 16:46 编辑

近期将进行: 函数式 编程 思路的部分数据结构的重新设计和改造 以及 测试验证。

尝试重新设计 原有的全部 map/hash_map/set/hash_set/btree等等 内存对象,通过 引入新的 函数式 编程思路,设计出
基于函数式编程思路的  map/hash_map/set/hash_set/btree等等 内存对象,在指令接口上尽量与传统 std库指令兼容,
在这些对象的并发性上将支持 无锁的读写分离技术(支持单线程写的同时,任意多线程同时读并发), 相当于任意时刻,内存对象的读都不需要加锁, 写需要加一把锁或者限制为单线程执行。

函数式 编程 思路,主要的优点是: 消灭部分 锁冲突,提高大并发下的性能。

先选择一个简单的数据结构 hash_set 进行 改造测试:
将 hash_set 改造为读写分离的结构,读不需要锁, 写需要一把锁 或者 单线程。

单线程读测试了一个 hash_set 的改造,性能下滑的幅度还比较大,性能降低了20%以上,
主要的原因是:所有的容器都用 一个先进的8字节大小的 支持读写分离的 共享指针封装, 每次使用 容器都需要一次 指针解析, 容器内部的单元也是用 共享指针封装的, 也需要一次 指针解析。
这样多次的 指针解析 降低了处理的效率。

另外就是在指令集上, 有很多指令需要改造 或者 引入新的使用方式,对于hash_set重点是:
下列指令将被取消, 因为底层容器会随时被替换掉
     iterator  begin( void ) noexcept;
     const_iterator  cbegin( void ) noexcept;
     iterator  next( iterator  &it_in );
     iterator  end( void ) noexcept;
     const_iterator  cend( void ) const noexcept;

需要将内部的数据结构引到外部, 例如:
   shared_ptr<std::vector<KEY_VALUE> >   get_shared_vector( void ) const noexcept;
上面的所有操作将在此结构上进行,另外
内部数据结构增加  is_valid() 验证函数, 供外部使用,
总之, 完全打破了 原来的各种 封装,导致了使用这种结构的技术风险, 兼容风险, 迁移风险。

由于没有锁保护,下列统计指令集将存在 非 repeatable read 的问题, 重复读 非一致, 需要注意:
     size_t  capacity( void ) const noexcept;
     size_t  rehash_count( void )  const noexcept;
     size_t  size( void )  const noexcept;
     size_t  total_inserted( void ) const noexcept;     
     size_t  count( const KEY &key_in ) const;  
     bool     empty( void ) const noexcept;

初步测试下来,结论是:引入 读写分离的hash_set需要谨慎,对于数据冲突不激烈的情况下, 性能反而会降低, 另外就是很多命令集与传统的使用方法不一样,并且存在 兼容风险, 迁移风险。
目前只适合小规模内测,暂时 不能够全面推广, 也不能够在产品上大规模引入使用。

论坛徽章:
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
发表于 2017-07-15 21:20 |显示全部楼层
关于 CRC32 的几个BUG:

1) Intel的硬件BUG:

最近 准备实现 intel SSE4.2的crc32c的LE模式,0x1EDC6F41(BE)/0x82F63B78(LE),以便实现一种crc64的计算模式,
我以前实现的是BE模式, 对应  boost::crc_optimal<32, 0x1EDC6F41, 0, 0, true, true>  d_boost_crc32
结果发现,LE模式 已经取消掉了,传说由于 硬件上存在BUG, 不能同时或者交错执行BE/LE指令, 会导致错误, 所以, 目前 Linux中也已经取消了LE模式的_mm指令。  
参考资料: https://en.wikipedia.org/wiki/SSE4
https://lists.gt.net/linux/kernel/956014

2)Boost 库的 软件BUG
  下面 uint_crc 不能设置为非零的值, 否则将计算错误, 但是手册中允许置为其他初值的
  d_boost_crc32.reset( uint_crc );
  d_boost_crc32.process_bytes( voids_in, size_length );
  return  d_boost_crc32.checksum();
并且
d_boost_crc32.reset( 100 );
  return  d_boost_crc32.checksum();  返回值不是100, 真是 莫名其妙。
当然这个BUG是可以绕过去的, 就是: d_boost_crc32.reset( 0 );   永远置设置0为初值。但是,适应的情况少了很多。
如果这个功能可用的话,可以预先来计算一部分crc,  例如: 事先知道某多个数据包的头部都是一样的,先计算完毕包头,存储起来,下次直接设置初值为前面计算的crc就可以免去重复计算包头了,只计算后续的字节,
现在Boost库就只好全部计算,唉。。。

论坛徽章:
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
发表于 2017-07-15 21:41 |显示全部楼层
本帖最后由 wlmqgzm 于 2017-07-15 21:43 编辑

关于 Boost 库 ASIO 发送函数 的一个BUG:

触发模式:发送2G Byte的数据,  接收使用telnet,  发送过程中,安全检查线程 巡检 检测到TCP/IP底层错误  

  struct tcp_info info;
  int length = sizeof(info);
  memset( &info,0,sizeof(info) );
  getsockopt( int_socket_handle, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&length );
  if( info.tcpi_state == 1 )   return false;
  return true;   //  这里检测到TCP/IP底层 错误

原因:Boost Asio 库发送时 缺乏对于 tcp_ip_send_buffer_free_bytes 的检测, 当TCP/IP的发送缓冲区已经写满了,试图写入数据,有时会导致此错误。
解决办法:
1)发送的大数据先切片为小数据,再发送,宁可多调用几次,
2)在发送 send  数据前检测 底层TCP/IP缓冲区 (默认2.5M大小), 如果空间快满了,则暂停发送
3)  暂停发送后,有一个共用的1秒定时器定期检查这些暂停的连接,当某连接的 底层TCP/IP 发送缓冲区已空后,重启发送任务继续发送。

论坛徽章:
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
发表于 2017-07-17 12:50 |显示全部楼层
本帖最后由 wlmqgzm 于 2017-08-09 15:55 编辑

关于 std::string 增加 resize_nofill

/usr/include/c++/5/bits/basic_string.h
      
原来只有: resize(size_type __n)  在resize(x) ,resize(y), y>x 都会在新增的长度空间中填充n个0

void  resize(size_type __n)
      { this->resize(__n, _CharT()); }

新增: resize_nofill,  主要用于 socket read 前  重置 std::string 的大小,如果   resize(x) ,resize(y), y>x,    y小于等于capacity(),  这种情况不需要填充零,
基本上  socket read 前  重置 std::string 都是属于不需要填充零的情况, 这样提高了性能。

      void
      resize_nofill(size_type __n)
      {
      if( size() <= __n && capacity() >= __n ) {
        _M_string_length = __n;
        return;
        }
      this->resize(__n, _CharT());
      return;
      }

论坛徽章:
12
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15摩羯座
日期:2014-07-21 10:11:2815-16赛季CBA联赛之八一
日期:2017-04-12 14:26:28
发表于 2017-07-17 13:53 |显示全部楼层
楼主,我建议代码还是按代码的方式贴,要不好难看

论坛徽章:
0
发表于 2017-07-25 17:07 |显示全部楼层
leveldb不是已经实现了吗?

论坛徽章:
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
发表于 2017-07-25 19:17 |显示全部楼层
本帖最后由 wlmqgzm 于 2017-07-25 21:30 编辑
yqw1122 发表于 2017-07-25 17:07
leveldb不是已经实现了吗?

我们研发的思路与 谷歌的 leveldb 是不太一样的,
在磁盘数据结构方面有很多改进, 总体是更快的性能。
另外, 我们也是很小的技术团队,没有拿到风险投资, 同时还有一些其他的项目在做, 研发速度上经常受限。


论坛徽章:
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
发表于 2017-08-28 19:17 |显示全部楼层
本帖最后由 wlmqgzm 于 2017-08-29 11:55 编辑

刚出了一个新版本, 将jemalloc又取消掉了,原因是jemalloc比较浪费内存,
例如: 4100字节的数据将会占用8KByte,  这样,对于内存数据库还是太浪费了,Tcmalloc也类似,还是gcc自带的ptmalloc好一些,
经过优化, 目前查询性能与以前使用jemalloc的版本基本一致,只有更新性能有下降,还可以接受。因为最重要的是查询性能。

先这样吧, 最起码不要浪费内存, 以后有时间的话, 有机会的话,期望实现一个超越jemalloc/tcmalloc/ptmalloc的,不浪费内存, 性能更好的malloc库,

您需要登录后才可以回帖 登录 | 注册

本版积分规则

SACC2017购票8.8折优惠进行时

2017中国系统架构师大会(SACC2017)将于10月19-21日在北京新云南皇冠假日酒店震撼来袭。今年,大会以“云智未来”为主题,云集国内外顶级专家,围绕云计算、人工智能、大数据、移动互联网、产业应用等热点领域展开技术探讨与交流。本届大会共设置2大主会场,18个技术专场;邀请来自互联网、金融、制造业、电商等多个领域,100余位技术专家及行业领袖来分享他们的经验;并将吸引4000+人次的系统运维、架构师及IT决策人士参会,为他们提供最具价值的交流平台。
----------------------------------------
优惠时间:2017年8月2日前

活动链接>>
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP