第二章:分布式系统基础设施
@分布式缓存
在高并发环境下,大量的读写请求涌向数据库,磁盘的处理能力与内存显然不在一个量级,从减轻数据库的压力和提高系统响应速度两个角度考虑,一般都会在数据库之前加一层缓存。
由于单台机器的内存资源和承载能力有限,并且如果大量使用本地缓存,也会使相同的数据被不同的节点存储多份,对内存资源造成极大的浪费,因此才催生了分布式缓存。
分布式缓存代表memcache,最为经典的场景莫过于分布式session。
安装memcache之前安装libevent,memcache使用libevent进行高效的网络连接处理
memcache本身并不是分布式的缓存系统,它的分布式是由访问它的客户端来实现的。它的分布式是由访问它的客户端来实现的。一种比较简单的实现方式是根据缓存的key来进行hash,当后端有N台缓存服务器时,访问的服务器为hash(key)%N,这样可以将前端的请求均衡地映射到后端的缓存服务器。
Hash(散列函数)概念
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
@分布式session
前端用户请求经过随机分发之后,可能会命中后端任意的Web Server,并且Web Server也可能会因为各种不确定的原因宕机。在这种情况下,session是难在集群间同步的,而通过将session以sessionid作为key,保存到后端的缓存集群中,使得不管请求如何分配,即便是Web Server宕机了,也不会影响其他Web Server通过sessionid从cache server中获得session,这样实现了集群间的session同步,又提高了Web Server的容错性。
@持久化存储
MySQL,HBase,Redis
MySQL提供完整的ACID操作,支持丰富的数据类型,强大的关联查询,where语句等。能够非常容易地建立查询索引,执行复杂的内连接,外连接,求和,排序,分组等操作,并且支持存储过程,函数等功能,产品成熟度高,功能强大。
HBase有更好的伸缩能力,更适合于海量的存储和处理,支持多个Region Sever同时写入,且性能出色,但难以支持复杂的条件查询。
Redis拥有更好的读写吞吐能力,能够支持更好的并发数,能提供更为丰富的数据类型支持,能更灵活地满足业务需求。
@MySQL扩展
1,业务拆分,企业运用业务规模发展壮大,对Single DB的访问造成极大压力,可将不同业务访问不同的数据库,也就是把Single DB(news,user,post,comment含有四个业务)拆分为多个数据库,如news,user,post,comment四个数据库,这样数据库压力变小,吞吐能力自然提高了,还能提高开发测试的效率,同时提升了系统的稳定性。
2,复制策略,当各台数据库服务器包含相同的数据时,前台运用通过访问MySQL集群中任意一台服务器,都能够读取到相同的数据,这样每台MySQL服务器所需承担的负载就会大大降低,从而提高整个系统的承载能力,达到系统扩展的目的。
要实现数据库的复杂,需要开启Master服务器端的Binary log。复制的过程实际上就是Slave从Master获取Binary log,然后再在本地镜像中执行日志中记录的操作。复制是异步的,因此Master和Slave之间的数据有可能存在延迟的现象,此时只能保证数据最终的一致性。
Master-Slaves复制架构一般会是这样的:
前段服务器通过Master来执行数据写入操作,数据的更新通过Binary log同步到Slave集群,而对于数据的读取请求,则交由Slave来处理,这样Slave集群可以分担数据库读的压力,并且读写分离还保障了数据能偶达到最终的一致性。
但是Master-Slave复制架构存在一个问题,即所谓的单点故障。当Master宕机,或者需要Master停机进行系统维护,优化,升级。这样会导致整个系统无法使用,那么最佳的方式是Dual-Master架构,也就是Master-Master架构。
3,分表和分库
复制策略中Slave的数量收到Master能力和负载的限制。因此,需要对数据库的吞吐能力进一步的扩展,以满足高并发访问与海量数据存储的需要。
对于访问极为频繁且数据量巨大的单表来说,我们首先要做的就是减少单表的记录条数,以便较少数据查询所需要的时间,提高数据库的吞吐,这就是所谓的分表。
分表能够解决单表数据量过大带来的查询效率下降的问题,但是无法给数据库的并发处理能力带来质的提升。面对高并发的读写访问,当数据库Master服务器无法承载读写操作压力时,不管如何扩展Slave服务器都是没用的。因此,我们必须换一种思路,对数据库进行拆分,从而提高数据库的读写能力,这就是所谓的分库。
有时数据库可能既面临着高并发访问的压力,又需要面对海量数据的存储问题,这时需要对数据库即采用分库策略,又采用分表策略,以便同事扩展系统的并发处理能力,以及提高单表的查询能力,这就是所谓的分库分表。
一般的分库分表的路由策略如下:
中间变量=user_id%(库数量*每个库的表数量)
库=取整(中间变量/每个库的表数量)
表=中间变量%每个库的表数量
假设用户user_id=262145,库数量=256,每个库的表数量=1024
中间变量=1
库=0
表=1
也就是,对于user_id=262145的订单记录的查询和修改,将被路由到第0个库第一个表
数据库经过业务拆分及分库分表后,虽然查询性能和并发处理能力提高了,但也会带来一些列的问题,比如,原本跨表的事物上升为分布式事务;由于记录被切分到不同的库与不同的表当中个,难以进行多表关联查询,并且不能不指定路由字段对数据进行查询。分库分表后,如果对系统内更进一步扩容(路由策略变更),将变得不方便,需要重新进行数据迁移。
@HBase
HBase是Apache Hadoop项目下的一个子项目,它以Google BigTable为原型,设计实现了高可靠性,高可扩展性,实时读写的列存储数据库。它的本质上是一张稀疏的大表,用来存储颗粒度的结构化数据,并且能够通过简单地增加节点来实现系统的线性扩展。
HBase运行在分布式文件系统HDFS上,利用它可以在廉价的PC Server上搭建大规模结构化存储集群。
Hadoop是一个由Apache基金会所开发的分布式系统基础架构,Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
Hadoop的发音是 [hædu:p]
Hadoop是一个能够让用户轻松架构和使用的分布式计算平台。用户可以轻松地在Hadoop上开发和运行处理海量数据的应用程序。它主要有以下几个优点:
高可靠性。Hadoop按位存储和处理数据的能力值得人们信赖。
高扩展性。Hadoop是在可用的计算机集簇间分配数据并完成计算任务的,这些集簇可以方便地扩展到数以千计的节点中。
高效性。Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。
高容错性。Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配。
低成本。与一体机、商用数据仓库以及QlikView、Yonghong Z-Suite等数据集市相比,hadoop是开源的,项目的软件成本因此会大大降低。
Hadoop大数据处理的意义
Hadoop得以在大数据处理应用中广泛应用得益于其自身在数据提取、变形和加载(ETL)方面上的天然优势。Hadoop的分布式架构,将大数据处理引擎尽可能的靠近存储,对例如像ETL这样的批处理操作相对合适,因为类似这样操作的批处理结果可以直接走向存储。Hadoop的MapReduce功能实现了将单个任务打碎,并将碎片任务(Map)发送到多个节点上,之后再以单个数据集的形式加载(Reduce)到数据仓库里。
@Redis
Redis是一个高性能的key-value数据库,与其他很多key-value数据库不同之处在于,Redis不仅支持简单的键值对类型的存储,还支持其他一系列丰富的数控存储结构,如strings,hashs,lists,sets,sorted sets等,并在这些数控结构类型上定义了一套强大的API。
Redis有更好的读写吞吐能力,能够支撑更高的并发数。
@消息系统
在分布式系统中,消息系统应用十分广泛,消息系统可以作为应用通信的一种方式。消息系统被保存在队列中,直到被接受者取出。由于消息发送者不需要同步等待消息接受者的相应,消息的异步接受降低了系统集成的耦合度,提升了分布式系统协作的效率,使得系统能够更快地响应用户,提供更高的吞吐。当系统处于峰值压力时,分布式消息队列还能够作为缓存,削峰填谷,缓解集群的压力,避免整个系统被压垮。
开源系统有很多,包括Apache的ActiveMQ,Kafka等
有点对点消息传输模型,发布/订阅消息传输模型
当一个应用部署到生产环境中,进行容错和避免单点故障是十分重要的,这样可以避免因为单个节点的不可用而导致整个系统的不可用,目前ActiveMQ所提供的高可用方案主要是基于Master-Slave模式实现的冷备方案,较为常用的包括基于共享文件系统的Master-Slave架构和基于共享数据库的Master-Slave架构。
@垂直化搜索引擎
这里介绍的垂直化搜索引擎,与Google,百度有一些区别,垂直化搜索引擎主要是针对企业内部的自有数据的检索,而不像Google和百度等搜索引擎平台,采用网络爬虫对全网进行抓取,从而建立索引提供给用户进行检索。
在分布式系统中,垂直化搜索引擎是一个非常重要的角色,它既能满足用户对于全文检索,模糊匹配的需求,解决数据库like查询效率低下的问题,又能解决分布式环境下,由于采用分库分表或者使用NoSQL数据库,导致无法进行多表关联或进行复杂查询的问题。
Lucene是全球范围内使用十分广泛的一个开源检索工具,它是Apache旗下的一个高性能,可伸缩的开源的信息检索库,最初是由Doug Cutting开发。
通过Lucene,可以十分容易地为应用程序添加文本搜索功能,而不必深入地了解搜索引擎实现的技术细节以及高深的算法,极大地降低了搜索引擎技术推广及使用的门槛。
Solr是一个基于Lucene,功能强大的搜索引擎工具,它对Lucene进行了扩展,提供了一系列功能强大的HTTP操作接口,支持通过Data Schema来定义字段,类型和设置文本分析。
@其他基础设施
除了前面提到的分布式缓存,持久化存储,分布式消息系统,搜索引擎,大型的分布式系统的背后,还依赖其他支撑系统,包括将要介绍的实时计算,离线计算,分布式文件系统,日志收集系统,监控系统,数据仓库等,此外还有CDN系统,负载均衡系统,消息推送系统,自动化运维系统等。