twemproxy架构分析——剖析twemproxy代码前编
twemproxy背景
在业务量剧增的今天,单台高速缓存服务器已经无法满足业务的需求, 而相较于大容量SSD数据存储方案,缓存具备速度和成本优势,但也存在数据安全性的挑战。为此搭建一个高速缓存服务器集群来进行分布式存储是十分必要的。
目前主流的高速缓存服务器是redis和memchache。而twemproxy是支持memcached和redis协议的轻量级代理中间件,能用于高速缓存服务器集群的搭建。为此,twemproxy是高速缓存服务器集群的核心组件之一,也是业界较为成熟的高速缓存服务器集群解决方案之一。
twemproxy概述
twemproxy是搭建分布式缓存集群的重要组件之一。他能将来自客户端的redis包通过key分片发送到不同的redis服务器,而不是发到单个redis服务器上。因此,可以使本来集中到一个redis上的信息被分流到多个redis上,这就使得 twemproxy能支持redis集群。
不难想到,因为twemproxy的分片功能,可以轻松地对redis集群进行水平扩展(简单地理解成在一个业务中加入更多的redis服务器),同时对于代码稍加改造,我们就可以得到能读写分离的redis集群,这大大将提高了redis集群的性能。这使得各大公司如豌豆荚、阿里、百度等都对于这份代码进行了修改,能使其满足分布式缓存集群的要求。当然,twemproxy并不负责数据一致性的工作。
源码下载地址:https://github.com/twitter/twemproxy/
twemproxy架构
为了能更好地了解twemproxy的代码结构,我们就需要了解twemproxy的架构,明白与它交互的组件。下面就是一般twemproxy的架构图
图1 twemproxy架构图
图1中,client是客户端,这里的客户端可以是很多应用,如网页,也可以是一些需要redis支持的服务器。LVS是Linux虚拟服务器,它主要用于负载均衡以及数据冗余,当然这一个层的负载均衡以及数据冗余也可以通过其他手段完成,如HAproxy等,当然也可以不需要这一层,可以让客户端直连twemproxy。memchache和redis是twemproxy目前支持的两种高速缓存服务器,但是考虑到高可用性和具体功能,一般会选用redis服务器。
我们可以看到在这种架构下,由于所有的通信都是用redis或者memchache协议完成。为此,client根本不知道和它通信的是高速缓存服务器还是twemproxy,高速缓存服务器memchache或redis也不知道和它联系的的是client还是twemproxy。
这样业务量一旦提升,我们只需要添加适量的高速缓存服务器和twemproxy服务器就可以满足业务需求。在这期间,几乎不需要对原先的client端的代码或者原先的高速缓存服务器的配置做任何修改,就可以完成业务上的水平扩容,这样就大大提高了高速缓存服务器的可用性。同时,由于不用修改client端的代码,我们可以进行平滑升级,即用户根本感知不到我们对业务进行了扩容,线上的client端不会因为我们的扩容而停止服务。同样地,我们可以对业务进行缩容处理。因此在业务量急剧变化的时候,这种架构的灵活性和可用性是原先单一的高速缓存服务器集群不能比拟的。
从这幅架构图上,我们也能开始逐一说明twemproxy的特性,阅读源码文件夹下的《README.md》的features,至于他是如何实现的,就需要我们去解读代码,这不是这一章要完成的任务。

图2 twemproxy特性
1.Fast,即快速,据测试,直连twenproxy和直连redis相比几乎没有性能损失,这已经很逆天了,最重要的是他还没有进行读写分离就能达到这样的效果,确实fast
2.Lightweight,即轻量级,就我个人而言,它代码量就是轻量级的,解压后仅仅1.8MB!!!!因为透明连接池,内存零拷贝以及epoll模型的使用,使得它足够快速和轻量级。
3.Enables pipelining of requests and responses,Keeps connection count on the backend caching servers low,即保持前端的连接数,减少后端的连接数,这里主要得益于透明连接池的使用,前端主要指的是client和lvs,后端指的是redis和memchache,这个好处特别明显,既可以减少了redis的连接负载,又保持了保持了前端的功能。
4.Enables pipelining of requests and responses,即将请求和回复管道化,这里我的理解是他将请求包和回复包一一对应起来后,使得它的请求和回复更明确。
5.Supports multiple server pools simultaneously,Shard data automatically across multiple servers,即它可以支持多个高速缓存服务器,以及能对高速缓存服务器的数据进行共享,这是通过我在前面讲到过twemproxy的分片功能来实现的。
6.Implements the complete memcached ascii and redis protocol,它支持memchache和redis这两个协议,当然现在只支持其中大部分的协议而不是全部,这个会在后面开章节专门说明。
7.Supports multiple hashing modes including consistent hashing and distribution.就是它支持很多哈希算法来哈希key,如crc32,crc16,MD5等等。
8.Easy configuration of server pools through a YAML file.它的配置文件是通过YAML文件来配置的,YAML文件好处是简单易懂,容易学习配置。
9.Can be configured to disable nodes on failures. 它会自动指出连接失败的节点并报警,就是一旦某个高速缓存服务器发生故障,它能感知到并报警。
10.Observability via stats exposed on the stats monitoring port.这是他的监控功能,一般比较少用,但是它提示的信息却有统计的价值,如统计发送了多少读写命令。
通过上述的功能分析,我们可以理出一个我们值得关注的实现上的功能列表:
1.内存管理,这是导致特性1和4的关键之一,他通过一些方法,如内存用完后不立即释放将其放入内存队列里以备它用,内存零拷贝等手段使内存使用效率大幅提高。对应源码中的nc_mbuf 文件。
2.透明连接池,这是导致特性1,3的关键之一,当然连接池内的连接同样的是使用完后不立即释放将其放入连接队列里以备它用。对应源码中的nc_connection 文件。
3.分片,这是导致特性5,6的关键,也是twenproxy的核心功能。当然后面的7,8也导致了分片能得以进行。对应源码中的proto文件夹、hashkit文件夹。
4.配置文件,这影响了特性8,同时这份代码在配置上的代码风格非常简约,对应源码中的nc_conf 文件。
5.监控,不是特别了解但是它完成了9,10特性,对应源码中的nc_proxy 、nc_stats 文件。
这些将是我们未来阅读剖析代码的一些重要关注点。
twemproxyLinux下安装
通过上述的描述,大家是否心动了,想要玩一下twemproxy,那么请大家与我一起安装twemproxy,当然安装twemproxy对于我们阅读twemproxy源码也会有所帮助。
1.首先安装autoconf2.69,这个请参考我的博文http://www.cnblogs.com/onlyac/p/5408420.html
2.进入源码目录
cd twemproxy
3.使用autoconf进行编译准备
autoreconf -fvi
./configure CFLAGS="-g -gstabs -O3 -fno-strict-aliasing" --enable-debug=full
4.编译以及安装
make && make install
这样编译以及安装完的程序nutcracker已在src目录下生成了。
未来我们也可以采用通过gdb来进行边走流程边看代码的一种阅读代码方式。
总结
在这篇文章中,我们首先概述了twemproxy,接着通过架构图展示,我们分析了该架构的优点,提取了会成为我们阅读源码的一些重要关注点和twemproxy的工作环境,最后阐述了如何安装twemproxy。
另外,对于博文有问题的请大家在评论中留言与博主讨论,博主会及时回复的!!!!
twemproxy架构分析——剖析twemproxy代码前编的更多相关文章
- twemproxy代码框架概述——剖析twemproxy代码前编
本篇将去探索twemproxy源码的主干流程,想来对于想要开始啃这份优秀源码生肉的童鞋会有不小的帮助.这里我们首先要找到 twemproxy正确的打开方式--twemproxy的文件结构,接着介绍tw ...
- twemproxy接收流程探索——twemproxy代码分析正编
在这篇文章开始前,大家要做好一个小小的心理准备,由于twemproxy代码是一份优秀的c语言,为此,在twemproxy的代码中会大篇幅使用c指针.但是不论是普通类型的指针还是函数指针,都可以让我们这 ...
- twemproxy接收流程探索——剖析twemproxy代码正编
本文旨在帮助大家探索出twemproxy接收流程的代码逻辑框架,有些具体的实现需要我们在未来抽空去探索或者大家自行探索.在这篇文章开始前,大家要做好一个小小的心理准备,由于twemproxy代码是一份 ...
- twemproxy发送流程探索——剖析twemproxy代码正编
本文想要完成对twemproxy发送流程--msg_send的探索,对于twemproxy发送流程的数据结构已经在<twemproxy接收流程探索--剖析twemproxy代码正编>介绍过 ...
- 剖析twemproxy前言
又是喜闻乐见的新坑,前面的mysql协议,当我在解读go-mysql包的时候,会重新讲到,至于Leetcode的更新会与go语言同步.关于这个redis的新坑,目前打算通过剖析twemproxy源码来 ...
- HashMap源码深度剖析,手把手带你分析每一行代码,包会!!!
HashMap源码深度剖析,手把手带你分析每一行代码! 在前面的两篇文章哈希表的原理和200行代码带你写自己的HashMap(如果你阅读这篇文章感觉有点困难,可以先阅读这两篇文章)当中我们仔细谈到了哈 ...
- 腾讯刘金明:腾讯云 EB 级对象存储架构深度剖析及实践
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 演讲者:刘金明 腾讯云存储业务中心副总监 背景:5月23-24日,以"焕启"为主题的腾讯"云+未来" ...
- 基于React的PC网站前端架构分析
代码地址如下:http://www.demodashi.com/demo/12252.html 本文适合对象 有过一定开发经验的初级前端工程师: 有过完整项目的开发经验,不论大小: 对node有所了解 ...
- 万字长文:ELK(V7)部署与架构分析
ELK(7版本)部署与架构分析 1.ELK的背景介绍与应用场景 在项目应用运行的过程中,往往会产生大量的日志,我们往往需要根据日志来定位分析我们的服务器项目运行情况与BUG产生位置.一般情况下直接在日 ...
随机推荐
- P2P网贷第三方托管模式存在5大缺陷,托管机构才是最大赢家
1.注册开户需要2次,用户体验很差劲儿. 理财人和借款人,首先在平台注册,然后还要在第三方托管账户注册. 很多类似的地方,用户体验非常差劲. 比如,密码4个. 平台:登录密码.交易密码 ...
- 解析ISO8583报文实例
http://www.cnblogs.com/1971ruru/archive/2012/12/10/2811549.html 本篇文章参考了中国银联POS终端规范,所以如有不明白的可以去我的资源里面 ...
- 【例题5-1 UVA 10474 】Where is the Marble?
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 排序 用lower_bound找就可以了. ->lower_bound,如果里面所有的数字都比x小,那么它的返回值会越界! [ ...
- 如何在 Linux 中统计一个进程的线程数
编译自:http://ask.xmodulo.com/number-of-threads-process-linux.html作者: Dan Nanni原创:LCTT https://linux.cn ...
- putty-gns3
hcl-cloud用的就是这个putty http://forum.gns3.net/topic5016.html File comment: Compiled PuTTY 0.62 for wind ...
- 【23.39%】【codeforces 558C】Amr and Chemistry
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 安装使用jupyter(原来的notebook)
1.安装pyzmq 使用pip install pyzmq,安装不成功. 使用easy_install.exe pyzmq.成功安装. 2.安装tornado pip tornado 安装完尚不成功. ...
- 【C++竞赛 H】The sum problem
Time Limit: 1s Memory Limit: 32MB 问题描述 Given a sequence 1,2,3,-,N, your job is to calculate the numb ...
- hadoop集群安装(多机,非伪集群)
1. 创建用户 创建hadoop用户组:sudo addgroup hadoop 创建hadoop用户:sudo adduser -ingroup hadoop hadoop 为hadoop用户分配r ...
- Android自定义组件系列【2】——Scroller类
在上一篇中介绍了View类的scrollTo和scrollBy两个方法,对这两个方法不太了解的朋友可以先看<自定义View及ViewGroup> scrollTo和scrollBy虽然实现 ...