支撑日活百万用户的高并发系统,应该如何设计其数据库架构? ?

腹黑的小忧郁王子璇


之前做过一个每天访问量达到800w的系统,简单说下自己的见解!

从整个应用系统来看,想要支持超高并发量,负载均衡,缓存,消息中间件,数据库读写分离,分库分表等必不可少,既然文章只问了数据库系统,那就只谈数据库!


数据库层面,一般无外乎是主从复制,读写分离,分库分表这些东西!

1,从单台数据库性能来看,单个mysql实例最大连接数为16384,就是说在同一时间最多能容纳那么多的访问量,同时受服务器CPU,内存,硬盘等的影响,但是在实际应用中能达到2000就不错了!

需要使用druid等数据库监控中间件,实时的监控数据库连接,sql效率等各种指标,在达到瓶颈之前找到办法,show status;这个指令也可以方便的查看数据库实例的各项指标

单台数据库实例配置最优化是保证整个数据库集群最优化的基本保证!

2,数据库集群:以分库分表为例,分库分表的方式有很多,比如mycat,Sharding-jdbc等。


分库分表的思想很简单,比如单表1亿的数据量,查询效率很低,如果使用8库1024表拆分,每张表中的数据不会超过10万,对数据库来说不存在任何瓶颈,就算总数据量达到100亿,单表的查询也不会慢!

拆分的策略通常以某个全局唯一的业务主键使用某种方式(比如hash取模,按月份等等)进行分库分表的计算!

那么问题来了,全局唯一的字段怎么获取?普通的数据库主键自增,uuid等不再合适,可以使用redis,zookeeper等获取全局唯一的id,具体可参见之前的其他回答!

问题:分库分表之后存在跨库join的问题,通常的解决方式为1,尽量使用分库分表主键能保证在同一库,同一类型的表中进行连接查询,2,增加专门的查询库:将常用的数据字段冗余到查询库中,方便连接查询和常用字段的快速查询;

4,sql优化:最基本的条件查询,count,分组等使用索引字段等避免全局查询,避免null值判断,避免使用not in,避免无效的like语句,避免查询的时候使用函数操作等等!

5,像秒杀系统等这种瞬时高并发,最好借助缓存系统来完成!

总而言之,数据库是整个应用系统当中最核心,也是最容易出问题的地方,做好监控,提前预防才能保证系统访问量的增长!


此生唯一


以mysql为列:

1:支撑高并发系统,一定会涉及事务,所以数据库引擎必选innodb,innodb支持事务,事务级别根据业务而定,如果业务数据一致性要求很高,事务就开启序列化级别,这样就完全隔离事务,但是会导致锁资源竞争加剧。mysql的性能有一定的降低。

2:读写分离,数据库分成主库和从库,主库负责写数据,丛库负责读数据。注意主从数据库数据一致性问题。

3:冷热数据分离,美团,饿了么部分设计采用冷热数据分离,拿订单来说,已送达订单,主要的业务场景就是查询,越往前的数据查询的概率就越低。这就是冷数据。正在交易的订单就是热数据,需要时时查询和更新。对于冷数据,可以放到redis缓存。这样会增加查询效率。

4:数据表设计,充分利用索引查询。业务sql避免返回无用的行和列,禁止使用select *查询,查询的时候加limit,尽可能返回满足要求的行。对于复杂的sql,考虑拆分sql,拆分sql有一个好处,重复查询的sql,第二次查询会放到mysql的缓冲区,避免重复操作磁盘,提高访问的性能。

5:分库分表。比如业务数据按月分等。一定程度缓解增删改查的压力。

希望对你有一定的帮助。谢谢。


猿问


这个问题的需求不够明确,主要是业务方面。

比如是一个百万日活的IM系统。

则百万日活的,假定有1000万用户的系统,用MYSQL基本可以不用分库分表(可以采用读写分离)。

主要是缓存系统的设计,常见的比如redis,可以用户全缓存在redis中,只有用户更改时才回写(回写也可以先写缓存,再异步刷入库中)。这样的设计,就用户表而言,基本是没有多少负载的。


真正复杂的是业务本身,比如是一个论坛,可能一天的新贴,回复等会产生巨量的数据。或是一个电商系统,商品,订单等。这些没有数据量都无法评估。

只是总体来看,用MYSQL(读写分离,分表设计)+缓存 是够用了。


分享到:


相關文章: