单机
缓存数据
通过NOSQL缓存数据,比如 redis、内存等;通过减少表连接的方式可以降低数据冗余,但是它牺牲了数据的一致性。
异步调用
为了保证数据的一致性,可以通过异步的方式更新缓存中的数据。
异步调用是把一些串行的方法并行化,从而提高响应的速率。异步调用需要考虑以下几点:
- 被调用方的结果返回,会涉及进程线程间通信的问题;
- 如果程序需要回滚,回滚会有点复杂;
- 异步通常都会伴随多线程多进程,并发的控制复杂;
- 如果是用消息机制,消息的丢失和乱序也会是比较复杂的问题。
熔断
如果外部调用的并发数超过本身系统的处理能力,可以通过熔断机制,拒绝或者二次处理来保护自身系统可用,从而保证即使面对大流量,系统也是可用的。
批量处理
网络上 MTU ,如果你的一个网络包没有放满这个MTU,那就是在浪费网络带宽。因为网卡的驱动程序只有一块一块地读效率才会高,所以网络发包时,我们需要收集到足够多的信息后再做网络I/O。
分布式
使用NoSQL数据库。
数据分区
数据表里的记录太多,导致关系型数据库操作太慢,可以通过对数据分区来解决该问题,一般数据分区的方式如下所示:
- 对数据分类。比如火车票的订票系统可以按各铁路局来分,可按各种车型分,可以按始发站分,可以按目的地分……反正就是把一张表拆成多张有一样的字段但是不同种类的表。这样,这些表就可以存在不同的机器上以达到分担负载的目的。
- 按字段切分数据。比如把一些不经常改的数据放在一个表里,经常改的数据放在另外多个表里。把一张表变成1对1的关系,这样,你可以减少表的字段个数,同样可以提升一定的性能。另外,字段多会造成一条记录的存储会被放到不同的页表里,这对于读写性能都有问题。但这样一来会有很多复杂的控制。
- 平均分表。因为第一种方法是并不一定平均分均,可能某个种类的数据还是很多。所以,也有采用平均分配的方式,通过主键ID的范围来分表。
- 对同一数据分区。这个在上面数据镜像提过。也就是把同一商品的库存值分到不同的服务器上,比如有10000个库存,可以分到10台服务器上,一台上有1000个库存。
NoSQL数据库因为它特有的分布式、数据互备概念,所以已经解决数据分区问题。
负载均衡
数据分区可以在一定程度上减轻负载,但是还是无法减轻热点数据的负载,需要使用数据镜像来减轻负载。Master-Slave 架构,由 Master 负责监控各个Slave 的负载情况,根据负载情况分配对应的数据。
总结
首先保证在单机情况下代码的响应度,性能上,都没有什么问题。最后再使用的 NoSQL 数据库、Spark、Flink 这些分布式系统来提升性能。