免费注册 查看新帖 |

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
41 [报告]
发表于 2016-05-13 10:40 |只看该作者
本帖最后由 wlmqgzm 于 2016-05-13 10:43 编辑

不积跬步,无以致千里.

初步决定, Memcached的接口一定要做, 只有先做了简单的接口, 测试实践积累经验后, 才能做成更多更好的事情.  好代码都是熬出来的.

用户接口层 与 存储层 之间的接口问题 开始考虑中............

初步的思路是: 双异步策略, 这样可以提供最大化的并发, 并且希望对象之间的耦合比较少. 那么可行的一个技术路径就是: 队列.
分为四类队列, 存储层查询队列, 存储层更新队列, 网络层接收查询结果队列, 网络层接收更新结果队列.

File_mapping 目前遇到的难题是: 层层封装之后, 高层代码对底层隔离了, 但是底层File存在需要动态扩展大小, 然后再ReMapping的问题, 以及写mapping在大小超过4G以后,淘汰前一个Mapping, 创建新文件和新Mapping,  层层传递失败返回结果的模式, 比较土,效率不高.
目前, 正在调整class的关系, 初步的思路是: 高性能代码要减少层级, 正在压缩中......   
昨天在考虑 存储层对象的智慧化, 还在考虑还有没有其他解决办法...................................

思考中:  mapping_region的shared_ptr 能否帮助实现更自动化的管理, 如何设计这部分代码流程......

论坛徽章:
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
42 [报告]
发表于 2016-05-13 10:56 |只看该作者
本帖最后由 wlmqgzm 于 2016-05-13 10:59 编辑

先上点干货,  谈几句时间的问题:

高性能的代码测试, 离不开高性能的时间函数. 以下代码都是本人亲自开发, 亲自调试过的东西. 都是现有的库,
前一段代码是Boost的库, 后一段代码是std的库
几乎同样字节数的代码, 性能差距超过20倍

先上一组 取时间的函数

//  性能太差了, 执行大约要16微秒
unsigned long long now_utc_useconds( void )
{
  return ( boost::posix_time::microsec_clock::universal_time() - ptiime_epoch ).total_microseconds();
}

//  性能太差了, 执行大约要16微秒
unsigned long long now_local_useconds( void )
{
  return ( boost::posix_time::microsec_clock::local_time() - ptiime_epoch ).total_microseconds();
}

//  性能太差了, 执行超过17微秒
void now_local_str( std::string &str_datetime )
{
  boost::posix_time::ptime ptime1 = boost::posix_time::second_clock::local_time();
  str_datetime =  boost::posix_time::to_iso_extended_string( ptime1 );
  return;
}

//  性能太差了, 执行超过17微秒
void now_utc_str( std::string &str_datetime )
{
  boost::posix_time::ptime ptime1 = boost::posix_time::second_clock::universal_time();
  str_datetime =  boost::posix_time::to_iso_extended_string( ptime1 );
  return;
}

再上一组高性能高精度的,
//  高性能, 高精度, 执行低于1微秒
unsigned long long now_utc_microseconds(void)
{
  std::chrono::time_point<std::chrono::system_clock> now1 = std::chrono::system_clock::now();
  unsigned long long  time_microseconds = std::chrono::duration_cast<std::chrono::microseconds>( now1.time_since_epoch() ).count();
  return time_microseconds;
}

//  高性能,高精度, 执行低于1微秒
unsigned long long now_utc_nanoseconds(void)
{
  std::chrono::time_point<std::chrono::system_clock> now1 = std::chrono::system_clock::now();
  unsigned long long  time_nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>( now1.time_since_epoch() ).count();
  return time_nanoseconds;
}

论坛徽章:
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
43 [报告]
发表于 2016-05-13 13:17 |只看该作者
本帖最后由 wlmqgzm 于 2016-05-16 00:50 编辑

上传一个 自己的网络库 制作的ECHO SERVER    echo_server_v1.01_linux (1.74 MB, 下载次数: 48)

性能在4核8线程3.4G主频的机器上,4线程做sever, 4进程ab测试, PingPong测试大约87万QPS,  测试工具是ab(Apache Benchmark),
单连接TCP测试, 1进程1连接 ab测试, PingPong测试大约11.2万QPS,

欢迎对比一下自己的网络库, 看一下性能对比.

网络库支持在线DEBUG抓包分析, 支持远程抓包分析.

Echo Server powered by Boost Asio.
Copy Right by Guo Zhong Ming 2016.05  Version 1.00
Echo Server Listen on port 1971
Echo Server Manage Listen on port 1972
Default use half number cpu.
type "Ctrl_C" will exit.
===============================================================

guo@guo-desktop:~$ telnet 127.0.0.1 1972
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Server Manage powered by Boost Asio.
Copy Right by Guo Zhong Ming 2016.05. Version 1.00
type "help" will show this.
type "status" will show all count.
type "undebug" will undebug all sockets.(default)
type "undebug 123 " will undebug socket 123.
type "undebug ip 192.168.1.3" will undebug remote ip =192.168.1.3
type "undebug ip port 192.168.1.3 8888" will undebug remote ip=192.168.1.3 and remote_port=8888
type "debug status" debug status
type "debug socket 123 " will debug socket 123
type "debug ip 192.168.1.3" will debug remote ip =192.168.1.3
type "debug ip port 192.168.1.3 8888" will debug remote ip=192.168.1.3 and remote_port=8888
type "message status" message status
type "message screen on" message show on screen
type "message screen off" message will not show on screen
type "message file on" message will write to file "debug_asio_tcp_socket.txt"
type "message file off" message will not write to file
type "message manage on" will show message on this socket
type "message manage off" will not show message on this socket
type "message level 1" only error message will output.(default)
type "message level 2" only error and warn message will output.
type "message level 3" error, warn, some log message will output.
>

论坛徽章:
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
44 [报告]
发表于 2016-05-16 22:23 |只看该作者
高性能存储层的代码, 主要困难在:
1) 多线程下编程的复杂性, 涉及到锁, PV等, 也涉及到随之带来的锁冲突.
2) 高性能编程的各类新技术的消化.
3) 尽可能取舍, 在一些情况下尽量用单线程来代替锁.

因此, 这部分代码编写比较慢, 修改也频繁, 明天开始写memcached命令集代码,  尽快进入调试阶段.

论坛徽章:
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
45 [报告]
发表于 2016-05-18 16:33 |只看该作者
本帖最后由 wlmqgzm 于 2016-05-19 22:33 编辑

存储层的Mapping写线程自动扩展文件大小, 进行写入, 不需要线程间同步的情况下, 读线程高效自动跟随扩展是如何实现的?

前面比较困扰的 mapping文件自动扩展大小后, 采用传统方案, re maping地址大小等参数全部要变化, 层层通知高层代码带来代码复杂化, 低效化, 多线程互相通知同步等等问题, 以及随之带来的可能线程进程冲突的问题.
全新的解决办法:  废弃掉老代码, 实现底层代码智能化的解决方案, 轻松搞定.
现在由于采用了底层代码智能化的方式, 稳定平滑, 不需要通知高层代码, 对高层代码透明, 对多线程透明

关键实现:
在检测到 底层读请求超边界后调用, ,
生成新内存对象, 用第2组虚地址 +前一组老的虚地址  共同指向同一个物理地址,保证平滑扩展, 旧内存对象保护起来, 等以后第2次扩展的时候释放, 保护其他多线程的操作,  这部分是虚内存, 不是物理内存, 因此不用马上释放, 也不能马上释放.
利用原子量计数保护, 实现 扩展函数 线程可再入, 还是没有使用锁.

所有的Mapping代码全部是全新的高性能无锁设计, 支持 多线程 高效并发.

读线程  扩展跟随  功能代码通过 "原子量+3组写内存屏障" 的新技术方案,
// 原子量计数保护, 实现 扩展函数 线程可再入
//  先  生成新内存对象 写屏障保证顺序
/ 再切换地址, 写屏障保证顺序
// 最后切换文件长度,  写屏障保证顺序
实现了稳定平滑文件扩展,   不需要线程间通知, 不需要层层代码通知, 无锁设计, 代码 线程安全, 线程可再入

论坛徽章:
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
46 [报告]
发表于 2016-05-19 22:05 |只看该作者
本帖最后由 wlmqgzm 于 2016-05-19 22:35 编辑

这2天把File_Mapping的代码理了一遍, 实现的机制上, 分为Mapping_read和Mapping_write 这2个对象,  读对象是多线程安全的, 可以并发读, 写对象是单线程驱动的.
分离的设计, 读对象可以无锁设计, 写对象单线程驱动, 也不用锁, 写对象更新数据后, 利用多组内存写屏障技术+offset隔离技术, 保证读对象读到的所有数据都是最新的.
读写分离的机制, 无锁的设计, 这些全新的设计理念, 为上层代码 有望提供非常好的性能.

后续准备再分离出第3个File_mapping对象, Mapping_lz4_write对象, 由于设计中, lz4_commpressHC消耗的资源还是比较大的, 把这部分设计单独拿出来, 用单独的线程驱动,
目前File_mapping的设计, 兼容linux和Windows, 关键的原因在于使用了 boost::interprocess::file_mapping 这个库, 比较简洁的实现了核心代码.

File_mapping层代码的实现上, 实现了无锁设计, 读Mapping所有需要锁的地方, 全部使用 内存写屏障 和 原子量 的办法解决了, 写Mapping是单线程,  因此, 预计File_Mapping层的代码 并发能力超强.
File_Mapping层的上层代码是Block层,  还在设计整理中, 有可能部分代码功能下推到File_Mapping, 部分上移到更高层, 最终彻底减少这个层次, 减少一个调用层级,  

论坛徽章:
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
47 [报告]
发表于 2016-05-20 21:46 |只看该作者
本帖最后由 wlmqgzm 于 2016-05-22 11:33 编辑

重新设计文件序列号,  分为主文件序列号和次序列号, 次序列号作为文件后缀, 从.000--.999,  一共1000组来表示同一个主文件.

修改的这部分设计, 主要是为了实现磁盘空间的多重备份, 数据可以有2个正在使用中的,
1个可用的文件主序列号(做文件名), 有000-999共1000个 次序列号循环使用(做后缀名) , 可实现有效数据至少有2个拷贝可读, 另外, 在虚拟地址空间给预留了2倍的地址(按照次序列号的奇偶区分), 保证可以地址不冲突.
旧的文件自动转移到备份目录中, 实现了动态自动备份的功能.

采用多重备份以后, 单一的文件损坏, 可以重新拷贝回来, 在重新启动后就会自动恢复, 不会造成数据丢失, 这个设计主要是在不增加额外IO的情况下, 增加一些代码将准备丢弃的旧文件作为备份数据, 可实现自动备份, 还是值得在早期的设计中预留这样的空间.
另外, lz4压缩由Mapping层, 直接修改为高层代码执行, 这样CPU的压力可以分摊到每个CPU上, 代码已经变更完毕.

Mapping层增加写文件结束标志, 就是在文件的末位写入 特殊构造的数据, 表示, 该文件已经写完, 后续空间为空, 写入已经切换到新的文件中继续. 也用于重启动后数据校验.
这个标志, 目前的设计方案就是一个空数据构造, 这部分代码已经完成.

论坛徽章:
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
48 [报告]
发表于 2016-05-22 12:49 |只看该作者

通用高性能无锁无等待队列---高并发高性能程序开发的关键技术

本帖最后由 wlmqgzm 于 2016-05-26 00:42 编辑

谈点高性能编程领域的一个关键技术:  

任意对象的无锁无等待队列.  一般线程间通讯采用 队列+锁的方式, 在高并发下, 锁成为瓶颈.  在实践中, 无锁无等待队列可解决这个瓶颈, 彻底提高性能

封装了2个 大对象的无锁/无等待队列,  实际实现就是std::shared_ptr 无锁/无等待队列(lock_free/ wait_free queue)的设计,  以便简化多线程编程中的线程通讯机制.

实际上现有的开放编程库中, 并不存在这样的工具. 所有这样的工具, 都是 关注高性能计算领域的公司 自己开发, 自己内部使用的核心代码, 不会公开.
自己重写了一遍.

在File_Mapping的底层代码上, File_Mapping_write 采用了std::shared_ptr无锁/无等待队列技术, 作为写请求的输入端,  单线程执行写,  准备将CPU的潜力发挥到极致.

下面是自己实现的其中1个高性能高并发队列2次封装

template<typename T, unsigned int N=WAIT_FREE_SPSC_QUEUE_DEFAULT_SIZE>
class  Wait_free_spsc_queue
{
  public:
     Wait_free_spsc_queue( void );
     bool push( std::shared_ptr<T>  sp_in );
     T*  pop(  void );
     unsigned int size( void );
     bool  empty( void );
     bool  full( void );
     bool is_lock_free( void );

  private:
.........................
};

论坛徽章:
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
49 [报告]
发表于 2016-05-23 09:21 |只看该作者
本帖最后由 wlmqgzm 于 2016-05-23 11:21 编辑

第1次做存储层的代码, 难度系数高, 并且希望实现最大的并发, 采用了各类所有能够采用的新技术, 花了大量时间在新技术的探索上,
本来这个帖子就是一个学习帖, 因此, 追求各类新技术到极致.

目前已有代码线程间的通讯已经彻底更换为无等待队列(Wait_free_queue),
包括(Wait_free_spsc_queue)单生产者单消费者 任意对象的Wait_free队列
包括(Wait_free_mpsc_queue)多生产者单消费者 任意对象的Wait_free队列
包括(Wait_free_spmc_queue)单生产者多消费者 任意对象的Wait_free队列
包括(Lock_free_mpmc_queue) 多生产者多消费者 任意对象的Lock_free队列

等等, 这些只在传说中存在的队列, 都被一一实现了,  Wait_free队列应该会比无锁(lock_free)队列有更高的并发, 无锁还是有等待状态的, Wait_free队列彻底没有等待了, 是目前世界上最先进的队列结构.
因此最近一段时间的开发, 反复修改的地方很多, 很多设计是改了又改, 代码废弃的数量也多.

基础的存储结构也反复修改, 目前最新的底层磁盘落地结构, 各类头尾以前大约是30多字节, 目前版本修改到18字节, 在最大限度的实现最优的解决方案.

论坛徽章:
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
50 [报告]
发表于 2016-05-23 18:48 |只看该作者
这个帖子最近都没有什么人来指导一下吗?  是不是很少有人做 存储层的 原因,  
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP