推荐文章:
[玩转MySQL之四]MySQL缓存机制
多数据源
我们常说的数据库压力过大崩溃,web服务器并发过大崩溃
MySQL:互联网公司常用分库分表方案汇总!
无论是IO瓶颈还是CPU瓶颈,都会导致数据库的连接数过大(默认是100,最大16384),最终达到连接数的最大阈值。
当负载过大时最直观的就是你发起一个请求等了三秒才响应出来,再增大请求数量时,需过一分钟再响应,此时浏览器
就认为超时,直接打不开,对外就是服务器崩溃。
其实服务器程序并没有退出,还在请求排队,只是处理不过来了。崩溃的原因是:一般请求一秒之内处理了,感觉不
到,随着请求增加,感觉就上来了,到达最大连接数服务器就开始丢弃部分请求,对外表现就是页面打不开服务器端
error,如果继续增大,你网卡硬件满负荷运载,就看你操作系统和硬件质量了。
数据库的连接数过大:
比如数据库的连接数最大是200,现在执行10查询语句,贼复杂那种,一个需要查10分钟,是不是得开启10个链
接?之后再来线程操作数据库,就得再多开一个连接。但如果你数据库不存在io瓶颈,你秒查,是不是只要开一个连
接就够了。
数据库崩溃:
崩溃是通俗的说法,意思是对外服务不正常了。。但是这个不正常是有语境的,比如我们淘宝买东西,应该几秒钟就提示
购买成功,但是如果10秒后才出来,这个就叫负载大,卡了。如果这个时间继续增大到30秒或者1分钟,浏览器就认为超
时了,直接显示打不开,那么对外就是宣称服务崩溃了。比如淘宝双11的时候很多页面打不开。但是实际上服务器上程序
并没有退出,只是处理不过来了。崩溃的原因是:服务器对于请求都是排队的,负载不大的时候感觉不到,因为都是1秒内
处理了。。当请求数量上去后,就开始有感觉了。但是继续增大的话,队列也满了,服务器开始丢弃部分请求继续增大网
络请求,操作系统的TCP协议栈也开始丢弃请求,对外表现为服务器网络也连不上了。继续增大的话,网卡硬件部分开始
满速运行,然后就看操作系统驱动和硬件质量了。。
分库分表的适用场景有两个:
- IO瓶颈
当热点数据太多,数据库缓存中放不下时,每次查询都会查询数据库造成大量的IO,降低查询速度。=>分库。
- CPU瓶颈
一. SQL语句 包含join ,groupby ,orderby 非索引字段条件查询、连表查询,会增加CPU负载运算,
这种情况需建立合适的索引,进行SQL优化,在业务逻辑层计算。
二. 单表数据量太大,查询时扫描的行太多,sql效率低,CPU负载大,出现瓶颈=>水平分表。
水平分库:
定义:表中字段多,检索用到的少,按照一定策略(hash、range等),把一个库中的数据拆分到多个库
中。
场景:系统并发量高,分表也是无济于事。
解决:库多了,单库里的数据也少了,CPU处理请求快了,io和CPU的压力自然成倍的缓解。
水平分表:
定义:按照一定策略(hash、range等),将一个表中的数据拆分到多个表中。
场景:并发量并不高,只是单表的数据量太多,影响SQL的效率,加重了CPU负担。
解决:分表后,表的数据量少了,单次SQL执行效率搞,CPU负担自然减轻。
垂直分库:
定义:按照业务属性不同,将不同的表拆分到不同的库中。
场景:系统并发量上来了,并且可以抽象出单独的业务模块。
解决:将这个表拆到单独的库中,甚至可以服务化。
垂直分表:
定义:按照字段的活跃性,将表中字段拆到不同的表中(主表和扩展表)
场景:系统并发不高,表的记录也不多,但是字段多,热点数据和非热点数据在一起,单行的数据占空间大,以至于,
数据库缓存中能被缓存的数据少,查询就会去读取磁盘上的数据,产生大量io,引发io瓶颈。
解决:垂直分表将热点数据放在一起作为主表,非热点数据作为扩展表,这样更多的热点数据能够被缓存到数据库的缓
存中,进而减少读io。比如淘宝商品页(数据小放缓存)和详情页。
拆分后最好不要用join,join的使用会增加CPU的负担还会把两个表关联耦合起来,关联数据最好在servic层做,分别获
取主表和扩展表数据然后用关联字段关联后获取。
SQL缓存级别:
一级缓存为sqlsession级别,即与数据库一次会话中同一个SQL文不会查多次,会直接到缓存中取。会话关闭缓存清空(存于内存中)。
二级缓存为namespace级别,也就是一个mapper.xml文件级别,多个mapper.xml有各自的缓存,查出的数据会别放到一级缓存中,当会话关闭后数据才会转移到二级缓存中(存于内存,内存不够存硬盘)。