分布式服务框架

10 篇文章 0 订阅

转载来源:http://blog.csdn.net/jakeswang/article/details/50605709
第2 章
分布式系统基础设施
chapter
第2 章 分布式系统基础设施 │ 59
一个大型、稳健、成熟的分布式系统的背后,往往会涉及众多的支撑系统,我们将这些支撑系统称为分布式系统的基础设施。除了前面所介绍的分布式协作及配置管理系统ZooKeeper,我们进行系统架构设计所依赖的基础设施,还包括分布式缓存系统、持久化存储、分布式消息系统、搜索引擎,以及CDN 系统、负载均衡系统、运维自动化系统等,还有后面章节所要介绍的实时计算系统、离线计算系统、分布式文件系统、日志收集系统、监控系统、数据仓库等。
分布式缓存主要用于在高并发环境下,减轻数据库的压力,提高系统的响应速度和并发吞吐。当大量的读、写请求涌向数据库时,磁盘的处理速度与内存显然不在一个量级,因此,在数据库之前加一层缓存,能够显著提高系统的响应速度,并降低数据库的压力。
作为传统的关系型数据库,MySQL 提供完整的ACID 操作,支持丰富的数据类型、强大的关联查询、where 语句等,能够非常容易地建立查询索引,执行复杂的内连接、外连接、求和、排序、分组等操作,并且支持存储过程、函数等功能,产品成熟度高,功能强大。但是,对于
需要应对高并发访问并且存储海量数据的场景来说,出于对性能的考虑,不得不放弃很多传统关系型数据库原本强大的功能,牺牲了系统的易用性,并且使得系统的设计和管理变得更为复杂。这也使得在过去几年中,流行着另一种新的存储解决方案——NoSQL,它与传统的关系型
数据库最大的差别在于,它不使用SQL 作为查询语言来查找数据,而采用key-value 形式进行查找,提供了更高的查询效率及吞吐,并且能够更加方便地进行扩展,存储海量数据,在数千个节点上进行分区,自动进行数据的复制和备份。
在分布式系统中,消息作为应用间通信的一种方式,得到了十分广泛的应用。消息可以被保存在队列中,直到被接收者取出,由于消息发送者不需要同步等待消息接收者的响应,消息的异步接收降低了系统集成的耦合度,提升了分布式系统协作的效率,使得系统能够更快地响
应用户,提供更高的吞吐。当系统处于峰值压力时,分布式消息队列还能够作为缓冲,削峰填谷,缓解集群的压力,避免整个系统被压垮。垂直化的搜索引擎在分布式系统中是一个非常重要的角色,它既能够满足用户对于全文检索、模糊匹配的需求,解决数据库like 查询效率低下的问题,又能够解决分布式环境下,由于采用分库分表,或者使用NoSQL 数据库,导致无法进行多表关联或者进行复杂查询的问题。

本章主要介绍和解决如下问题:

 分布式缓存memcache 的使用及分布式策略,包括Hash 算法的选择。
 常见的分布式系统存储解决方案,包括MySQL 的分布式扩展、HBase 的API 及使用
场景、Redis 的使用等。
 如何使用分布式消息系统 ActiveMQ 来降低系统之间的耦合度,以及进行应用间的通信。
 垂直化的搜索引擎在分布式系统中的使用,包括搜索引擎的基本原理、Lucene 详细的
使用介绍,以及基于Lucene 的开源搜索引擎工具Solr 的使用。

60 │ 大型分布式网站架构设计与实践
2.1 分布式缓存
在高并发环境下,大量的读、写请求涌向数据库,磁盘的处理速度与内存显然不在一个量级,从减轻数据库的压力和提高系统响应速度两个角度来考虑,一般都会在数据库之前加一层缓存。由于单台机器的内存资源和承载能力有限,并且如果大量使用本地缓存,也会使相同的
数据被不同的节点存储多份,对内存资源造成较大的浪费,因此才催生出了分布式缓存。本节将详细介绍分布式缓存的典型代表memcache,以及分布式缓存的应用场景。最为典型的场景莫过于分布式session。
2.1.1 memcache 简介及安装

memcache1是danga.com 的一个项目,它是一款开源的高性能的分布式内存对象缓存系统,最早是给 LiveJournal2提供服务的,后来逐渐被越来越多的大型网站所采用,用于在应用中减少对数据库的访问,提高应用的访问速度,并降低数据库的负载。
为了在内存中提供数据的高速查找能力,memcache 使用 key-value 形式存储和访问数据,在内存中维护一张巨大的HashTable,使得对数据查询的时间复杂度降低到O(1),保证了对数据的高性能访问。内存的空间总是有限的,当内存没有更多的空间来存储新的数据时,memcache就会使用LRU(Least Recently Used)算法,将最近不常访问的数据淘汰掉,以腾出空间来存放新的数据。memcache 存储支持的数据格式也是灵活多样的,通过对象的序列化机制,可以将更高层抽象的对象转换成为二进制数据,存储在缓存服务器中,当前端应用需要时,又可以通过二进制内容反序列化,将数据还原成原有对象。
1. memcache 的安装
由于 memcache 使用了libevent 来进行高效的网络连接处理,因此在安装memcache 之前,
需要先安装libevent。
下载 libevent3,这里采用的是1.4.14 版本的libevent。
wget https://github.com/downloads/libevent/libevent/libevent-1.4.14bstable.
tar.gz
1 memcache 项目地址为http://memcached.org
2 LiveJournal,http://www.livejournal.com
3 libevent,http://libevent.org
第2 章 分布式系统基础设施 │ 61
解压:
tar –xf libevent-1.4.14b-stable.tar.gz
配置、编译、安装libevent:
./configure
make
62 │ 大型分布式网站架构设计与实践
sudo make install
下载memcache,并解压:
wget http://www.memcached.org/files/memcached-1.4.17.tar.gz
tar –xf memcached-1.4.17.tar.gz
配置、编译、安装memcache:
./configure
第2 章 分布式系统基础设施 │ 63
make
sudo make install
64 │ 大型分布式网站架构设计与实践
2. 启动与关闭memcache
启动memcache 服务:
/usr/local/bin/memcached -d -m 10 -u root -l 192.168.136.135 -p 11211 -c 32
-P /tmp/memcached.pid
参数的含义如下:
 -d 表示启动的是一个守护进程;
 -m 指定分配给memcache 的内存数量,单位是MB,这里指定的是10 MB。
 -u 指定运行memcache 的用户,这里指定的是root;
 -l 指定监听的服务器的IP 地址;
 -p 设置memcache 监听的端口,这里指定的是11211;
 -c 指定最大允许的并发连接数,这里设置为32;
 -P 指定memcache 的pid 文件保存的位置。
关闭memcache 服务:
kill cat /tmp/memcached.pid
2.1.2 memcache API 与分布式
memcache 客户端与服务端通过构建在TCP 协议之上的memcache 协议4来进行通信,协议
支持两种数据的传递,这两种数据分别为文本行和非结构化数据。文本行主要用来承载客户端
的命令及服务端的响应,而非结构化数据则主要用于客户端和服务端数据的传递。由于非结构
化数据采用字节流的形式在客户端和服务端之间进行传输和存储,因此使用方式非常灵活,缓
存数据存储几乎没有任何限制,并且服务端也不需要关心存储的具体内容及字节序。
memcache 协议支持通过如下几种方式来读取/写入/失效数据:
4 memcache 协议见https://github.com/memcached/memcached/blob/master/doc/protocol.txt
第2 章 分布式系统基础设施 │ 65
 set 将数据保存到缓存服务器,如果缓存服务器存在同样的key,则替换之;
 add 将数据新增到缓存服务器,如果缓存服务器存在同样的key,则新增失败;
 replace 将数据替换缓存服务器中相同的key,如果缓存服务器不存在同样的key,则替
换失败;
 append 将数据追加到已经存在的数据后面;
 prepend 将数据追加到已经存在的数据前面;
 cas 提供对变量的cas 操作,它将保证在进行数据更新之前,数据没有被其他人更改;
 get 从缓存服务器获取数据;
 incr 对计数器进行增量操作;
 decr 对计数器进行减量操作;
 delete 将缓存服务器上的数据删除。
memcache 官方提供的Memcached-Java-Client5工具包含了对memcache 协议的Java 封装,
使用它可以比较方便地与缓存服务端进行通信,它的初始化方式如下:
public static void init(){
String[] servers = {
“192.168.136.135:11211”
};
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(servers);//设置服务器
pool.setFailover(true);//容错
pool.setInitConn(10);//设置初始连接数
pool.setMinConn(5);//设置最小连接数
pool.setMaxConn(25); //设置最大连接数
pool.setMaintSleep(30);//设置连接池维护线程的睡眠时间
pool.setNagle(false);//设置是否使用Nagle 算法
pool.setSocketTO(3000);//设置socket 的读取等待超时时间
pool.setAliveCheck(true);//设置连接心跳监测开关
pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);//设置Hash 算法
pool.initialize();
}
通过 SockIOPool,可以设置与后端缓存服务器的一系列参数,如服务器地址、是否采用容
5 Memcached-Java-Client,https://github.com/gwhalin/Memcached-Java-Client
66 │ 大型分布式网站架构设计与实践
错、初始连接数、最大连接数、最小连接数、线程睡眠时间、是否使用Nagle 算法、socket 的
读取等待超时时间、是否心跳检测、Hash 算法,等等。
使用 Memcached-Java-Client 的API 设置缓存的值:
MemCachedClient memCachedClient = new MemCachedClient();
memCachedClient.add(“key”, 1);
memCachedClient.set(“key”, 2);
memCachedClient.replace(“key”, 3);
通过 add()方法新增缓存,如果缓存服务器存在同样的key,则返回false;而通过set()方法
将数据保存到缓存服务器,缓存服务器如果存在同样的key,则将其替换。replace()方法可以用
来替换服务器中相同的key 的值,如果缓存服务器不存在这样的key,则返回false。
使用 Memcached-Java-Client 的API 获取缓存的值:
Object value = memCachedClient.get(“key”);
String[] keys = {“key1”,”key2”};
Map

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值