不用改软硬件设计,只需要增加或者减少服务器的数量就能够扩大或减少网站的处理能力
网站伸缩性设计
不同功能进行物理分离实现伸缩
纵向分离,分层分离。 通常是网站-复用业务-基础技术服务-数据库
横向分离,按业务分。买家,卖家,论坛,详情,列表页
单一功能通过集群实现伸缩
一头牛拉不动就让两头来
分为应用服务器集群,缓存数据服务器集群,和存储数据服务器集群。
应用服务器集群的伸缩性设计
负载均衡, 能够识别新加入的服务器,对请求进行转发。
HTTP重定向负载均衡
DNS服务器解析到重定向服务器。重定向服务器通过一定的算法来算出真是服务器通过302返给浏览器,浏览器重新请求道真是服务器。
缺点:两次定位,重定向服务器会成为瓶颈,可能会被搜索引擎判断为作弊
DNS域名解析负载均衡
DNS服务器在解析ip的时候就做一次负载均衡。缺点因为是多级解析可能有缓存导致发请求到已经下线的机器上。
比较常用,会作为第一道负载均衡
反向代理负载均衡
反向代理服务器除了做缓存外还能做负载均衡。 要配置双网卡,内网卡可以用比较好的,提高性能。其是对HTTP协议的转发,又叫应用层负载
缺点是其本身可能成为瓶颈。
IP负责均衡
在服务器系统内核获取数据包,修改数据的目的ip地址,得到返回之后修改源地址。 这样在内核层面比反向代理的效率要高,但是对于视频等网站带宽会成为瓶颈。最好是能够让每个服务器自己发返回请求给浏览器。
数据链路层负载均衡
三角传输
不修改数据的目的和源ip,而是修改mac地址。
响应数据不通过负载均衡服务器,而是直接返给浏览器。 开源产品叫做LVS。
负载均衡算法
- 轮询 依次发送
- 加权轮询 根据硬件性能加权。使性能更好的机器获得更多的请求
- 随机 随机本身就很均衡
- 最少连接 记录服务器正在处理的连接数,将新到的分到连接最少的, 这个最符合负载均衡的定义
- 源地址散列 将一个ip的请求总是发往同一个服务器
分布式缓存集群的伸缩性设计
因为各个集群节点的数据不同,所以不能用简单的负载均衡实现,要做到增删阶段对原有数据的影响最小。
Memcached分布式缓存集群的访问模型
使用key访问api,api通过路由算法从服务器列表中找到对应的服务器,通过通信模块访问服务器
伸缩性
余数hash, 但是如果增删阶段会带来服务命中,会需要大量时间进行数据迁移。
一致性hash算法:
构建一致性hash环, 服务器节点放在环上,根据key算起hash值,然后顺时针查找最近的服务器节点。
新增节点是,加到换上,比如加到key0和key3之间。 这个时候只有key3会因为新加入的节点导致了无法命中,是比较少的一部分。
具体实现可以使用二叉树。
有一个问题就是有可能不平衡, 解决方式:计算机的任何问题都可以通过增加一个虚拟层来解决。
将一个真实服务器映射为hash环上的多个虚拟阶段,这样新增的时候就会比较均衡的影响比较多的节点。经验是150比较合适
数据存储服务器集群的伸缩性设计
因为对可用性持久性有要求,所以跟缓存的设计不一致。
关系型数据库集群的伸缩性设计
主从
读写分离
分库
分片
Cobar
用于集群数据分片,是一个数据库的访问代理
如图Cobar本身可以做集群,这个因为无状态可以使比较简单的负载均衡
mysql做集群。需要考虑一致性hash算法。新增节点是要考虑数据的一致性,可访问性,迁移过程中服务器宕机时可用性等问题。
实践方案,cobar用mysql的数据同步功能进行数据迁移。以Schema(mysql就是对应到库名)为单位。每个mysql实例创建多个Schema。扩展式从每个mysql中迁移一部分到新的机器。然后增加路由,删除原schemal
这样做不能join,不join的时候访问速度跟不用cobar差不多。
只能利用事务补偿机制来代替事务。
nosql数据库的伸缩性设计
关系型数据库的问题:糟糕的海量数据处理能力及僵硬的设计约束
nosql强调高可用和可伸缩性。 忽略SQL和ACID
HRegionServer是一个物理机,可以启动多个HRegion. HRegion是一个数据单元,里面保存多组key,value.
如果HRegion过多会分裂,并重新分配到HRegionServer中, 并且记录在HMaster中
HRegion会把数据写入到HFile格式的文件中,这些文件使用HDFS分布式文件系统
使用多个HMaster, 使用zookeeper做分布式一致性选举找到HMaster.