可扩展架构后续
遗留问题
如何解决水平扩展系统中的缓存和会话等状态问题?
使用负载均衡器,如HAProxy,使得系统能够水平扩展。
但是由于请求被分发到不同的backend,在原来的web系统中间,如果使用了缓存技术,在某一个服务实例上面生成了缓存,因为下一个请求可能不发送到它那儿,所以缓存没有发挥它的直接作用,导致缓存的优势没有发挥出来。更严重的是说,如果应用本身是带状态的(虽然http本身是一个无状态协议,但是可以通过session和cookie来实现多个请求放置在一个会话中间来管理),请求被发送到不同的服务实例上面:在前一次请求到达的服务实例上面所维护的会话状态在下一个服务实例上面是没有的,这就会导致会话在管理上存在问题
Cache
每个Cache都维护自己独立的缓存的话,代价很高。解决这个问题最简单的方法就是所有的server共享一个cache
在Spring中使用这个技术:
Redis缓存服务器
用redis做缓存服务器的问题:单点失效
可能redis服务器宕机,整个系统的缓存服务就失效了
而且如果系统过大,可能成为系统的性能瓶颈
解决方法:
问题是如何进行数据分区
- 哈希Hash Partitioning
- 一致性哈希 Consistent Hashing
哈希划分容易在节点扩充和缩减的时候,造成位置的偏差,很多cache失效
解决方法:一致性哈希
节点扩充和节点缩减只会导致部分节点失效
会话问题的解决
HAPROXY可以帮忙实现
在Tomcat中,每个节点会与其它节点的会话数据进行同步
缺点就是效率很低,所以会限定服务器的集群是3 - 5个左右
Spring中直接用SQL数据库保存会话数据。因为会话对象的数据量不是很大,所以这种方法是行得通的(但是尽量不适用,用Redis)。