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。