高并发学习入门-1

高并发 - 扩容

垂直扩容(纵向扩展) : 提高系统部件能力

比如:增加内存垂直扩容的主要是提高系统部件的能力,但会增大单个服务中其他软件设施的依赖与管理、服务内部复杂度

水平扩容(横向扩展) : 增加更多系统成员来实现

比如:加服务器实现水平扩容主要是增加更多的成员来分担压力,但会增加网络、数据库 IO 开销、管理多个服务器的难度

扩容 - 数据库

读操作扩展

加缓存,结合 memcathe、redis、CDN 等构建一个健壮的缓存系统。如果系统超负荷运行,将更多的数据放在缓存中来缓解系统的读压力。采用水平扩容没有太大的意义,因为性能的瓶颈不在写操作,所以不需要实时去完成,用更多的服务器来分担压力性价比太低。所以针对单个系统去强化它的读性能就可以了

写操作扩展

如 Cassandra、Hbase 等。和大多数的关系型数据库不同,这种数据存储会随着增长增加更多的节点。也可以考虑垂直扩容提升单个数据库的性能,但会发现资金与硬盘的 IO 能力是有限的,所以需要增加更多数据库来分担写的压力。

高并发 - 缓存

缓存特征

1.命中率 : 命中数/(命中数+未命中数)

2.最大元素(最大空间)

3.清空策略

缓存分类

1.本地缓存

2.分布式缓存:Memcache,redis

缓存常见问题

1.缓存一致性

数据库的数据和缓存中的数据保持一致.

2.缓存并发问题

获取缓存的时候加锁,获取完释放锁

3.缓存穿透

一般的缓存系统,都是按照 key 去缓存查询,如果不存在对应的 value,就应该去后端系统查找(比如 DB)。一些恶意的请求会故意查询不存在的 key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免?

3-1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。

3-2:对一定不存在的 key 进行过滤。可以把所有的可能存在的 key 放到一个大的 Bitmap 中,查询时通过该 bitmap 过滤。

4.缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免?

4-1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。

4-2:做二级缓存,A1 为原始缓存,A2 为拷贝缓存,A1 失效时,可以访问 A2,A1 缓存失效时间设置为短期,A2 设置为长期

4-3:不同的 key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

高并发 - 消息队列

消息队列特征

1.与业务无关,只做消息分发

2.FIFO.先投递先到达

3.容灾,节点的动态增删和消息的持久化

4.性能,吞吐量提升,系统内部效率提高

消息队列的好处

1.解耦

2.削峰,流量控制

3.异步,最终一致性

4.广播

高并发 - 应用拆分

拆分原则:

1.业务优先,确定业务边界

2.循序渐进,边拆分边测试

3.兼顾技术:重构,分层

4.可靠测试

拆分的思考:

1.应用之间的通信:RPC(dubbo 等)、消息队列
消息传输适用于传输数据包小但是数据量大,对实时性要求不高的场景。比如下单成功后通过短信通知用户。而选用 RPC 框架实时性更高一些。你应该知道的 RPC 原理

2.应用之间的数据库设计:每个应用都有独立的数据库

3.避免事务操作跨应用,分布式事务是一个非常消耗资源的问题。这样应用和应用的耦合度降低。

应用服务化(Dubbo RPC,Spring Cloud 微服务)