用muduo实现memcached协议的例子

简介:

最近花了两天时间用 muduo 部分实现了 memcached 服务器协议,代码位于 examples/memcached/server,能通过 memcached 的大部分测试用例(incr/decr 还没有实现)。

这不是 memcached 的替代品(它没有实现LRU和超时功能,也没有实现二进制协议,更没有自己管理内存),而是一个网络编程的示例(代码只有 1000 行,比 memcached 小很多),展示 muduo 风格的事件驱动编程,以及将来性能优化的试验品(换句话说,现在这个版本完全没有在性能上做出任何努力)。读过 memcached 代码的人可以对比这两种编程风格的区别,memcached 的 read/write 操作穿插于正常逻辑处理,而 muduo 的网络数据读写是由库完成,应用程序只关心消息收发,目前二者的基本 get/set 操作的性能相当。

现在 muduo 的 inspector 内置了 gperftools 的远程 profiling 功能,memcached-debug 展示了其用法。

为什么不必优化 set 操作(含 set/add/update/append/prepend/cas 等)的性能?

1. 比例。既然是 memcache,那么 get:set 的比例很高,10:1 甚至更高,因此优化的重心应该是 get 而非 set。

假设 memcached 能处理 100k QPS,再假设这些操作都是 set(其实应该不到 10% 是 set),再假设所有的 set 都是串行执行的(没有并发),那么每次 set 的 CPU 时间不应该超过 10 us(含服务器本地的网络代码运行时间,但不含网络延迟)。而实际上一次 set 的 CPU 时间最多是 2~3 us (用 memcached-footprint 程序测得),根本不值得优化。

2. 网络带宽。假设一次 set 操作的 key + value 的长度是 1k bytes,TCP 的有效载荷带宽按110MB/s估算,那么1kB数据在千兆网上的惯性延迟是 9us(传输延迟是几十上百微秒,与此无关),也就是说服务器的网卡收到这 1kB 数据需要花 9us 时间(从第一个字节到达到服务器到收完最后一个字节),那么在 set 耗时 2~3 us 的情况下再去优化它是做无用功。

3. 产生“需要更新的数据”的成本远大于 memcached set 的开销。memcached 需要更新,往往是将已写入数据库的新数据放到 memcached 中,那么写数据库的开销远远大于 memcached set 的开销,优化 set 对提升系统整体性能没意义。


    本文转自 陈硕  博客园博客,原文链接:http://www.cnblogs.com/Solstice/p/3265852.html,如需转载请自行联系原作者




相关文章
|
8月前
muduo源码剖析之Connector客户端连接类
Connector负责主动发起连接,不负责创建socket,只负责连接的建立,外部调用Connector::start就可以发起连接,Connector具有重连的功能和停止连接的功能,连接成功建立后返回到TcpClient。
64 0
|
8月前
|
网络协议 Linux C++
Linux C/C++ 开发(学习笔记十一 ):TCP服务器(并发网络网络编程 一请求一线程)
Linux C/C++ 开发(学习笔记十一 ):TCP服务器(并发网络网络编程 一请求一线程)
159 0
|
7月前
|
NoSQL Java Redis
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
106 0
|
4月前
|
网络协议 C语言
C语言 网络编程(十三)并发的TCP服务端-以进程完成功能
这段代码实现了一个基于TCP协议的多进程并发服务端和客户端程序。服务端通过创建子进程来处理多个客户端连接,解决了粘包问题,并支持不定长数据传输。客户端则循环发送数据并接收服务端回传的信息,同样处理了粘包问题。程序通过自定义的数据长度前缀确保了数据的完整性和准确性。
|
4月前
|
网络协议 C语言
C语言 网络编程(十四)并发的TCP服务端-以线程完成功能
这段代码实现了一个基于TCP协议的多线程服务器和客户端程序,服务器端通过为每个客户端创建独立的线程来处理并发请求,解决了粘包问题并支持不定长数据传输。服务器监听在IP地址`172.17.140.183`的`8080`端口上,接收客户端发来的数据,并将接收到的消息添加“-回传”后返回给客户端。客户端则可以循环输入并发送数据,同时接收服务器回传的信息。当输入“exit”时,客户端会结束与服务器的通信并关闭连接。
|
4月前
|
网络协议 C语言
C语言 网络编程(十一)TCP通信创建流程---服务端
在服务器流程中,新增了绑定IP地址与端口号、建立监听队列及接受连接并创建新文件描述符等步骤。`bind`函数用于绑定IP地址与端口,`listen`函数建立监听队列并设置监听状态,`accept`函数则接受连接请求并创建新的文件描述符用于数据传输。套接字状态包括关闭(CLOSED)、同步发送(SYN-SENT)、同步接收(SYN-RECEIVE)和已建立连接(ESTABLISHED)。示例代码展示了TCP服务端程序如何初始化socket、绑定地址、监听连接请求以及接收和发送数据。
|
8月前
|
网络协议
muduo源码剖析之TcpClient客户端类
muduo用TcpClient发起连接,TcpClient有一个Connector连接器,TCPClient使用Conneccor发起连接, 连接建立成功后, 用socket创建TcpConnection来管理连接, 每个TcpClient class只管理一个TcpConnecction,连接建立成功后设置相应的回调函数。很显然,TcpClient用来管理客户端连接,真正连接交给Connector。
102 0
muduo源码剖析之TcpClient客户端类
|
8月前
|
网络协议 算法
muduo源码剖析之TcpConnection连接管理
TcpCon用于管理一个具体的 TCP 连接,比如消息的接收与发送,完成用户指定的连接回调 connectionCallback。TcpConnection 构造时接收参数有 TCP 连接的 sockfd,服务端地址 localAddr,客户端地址 peerAddr,并通过 Socket 封装 sockfd。并用 Channel 管理该 sockfd,向 Channel 注册可读、可写、关闭、出错回调函数,用于 Poller 返回就绪事件后 Channel::handleEvent() 执行相应事件的回调。
98 0
muduo源码剖析之TcpConnection连接管理
|
缓存 移动开发 网络协议
TCP编写服务器,客户端以及遇到的两个问题,Socket,ServerScket 类,flush(),方法。以及多线程解决,及改进的线程池写法,IO多路复用的思想,C10K,C10M的阐述。万字超细
TCP编写服务器,客户端以及遇到的两个问题,Socket,ServerScket 类,flush(),方法。以及多线程解决,及改进的线程池写法,IO多路复用的思想,C10K,C10M的阐述。万字超细
|
存储 缓存 NoSQL
Redis网络层源码阅读
Redis 离用户最近的就是网络层了,网络层不负责命令的具体执行,只负责网络数据的收发,虽然它不负责具体的功能实现,却是Redis单线程,高性能的核心。
219 0