分库分表

分库分表

拆分的目的是什么?

拆库,还是拆表?两者结合?

拆库方便进行扩容

其规则设计的好,表也可以移动

拆成多少合适

单实例最多1千张表

单表按1千万~1亿条数据规划,10G左右

对于大字段blob,text字段建议拆分并压缩,用主键关联(查询)

每个表必须有主键,主键采用自增int/bigint

单库200~400张表

Hash拆分

拆分成10库10表

dbRule: db + (id/10 % 10)

tbRule: t + (id % 10)

Range拆分

id < 1千万在DB0

1千万 <= id <2千万 DB1

按日期拆分

create_time按月一个表 

按业务垂直拆分

用户基本资料库

好友关系库

等等

数据库拆分后续

拆分策略最好一开始就想清楚,不要在实施过程中多变

优先采用可控性强的策略,也就是更方便后续扩展的策略

不单纯追求拆分后的均衡离散性 

拆分之后,需要选择一个合适的proxy方案

不一定非要proxy,单整体改造代价一定不能太高

proxy方案选择更适合自己场景的

数据分级决定缓存策略不同

第一级:订单数据和流水数据,这两块数据对实时性和精确性要求很高,所以不添加任何缓存,读写操作将直接操作数据库 

第二级:用户相关数据,这些数据和用户相关,具有读多写少的特征,所以我们适用redis进行缓存

第三级:配置信息,这些数据和用户无关,具有数据量小,频繁读,几乎不修改的特征,可以使用本地内存进行缓存 

架构方案关键点 

如何保证多节点的写入可用性

keepalived+双主,但只写一个节点

PXC,多库多表并行写入

MHA,一主多从,或者双主多从

大杀器,MGR 

如何提高读可用性

一主一从,从故障时切换到主

一主多从,多从可做高可用,或者根据情况切到主

双主多从,同上

写压力分摊

垂直拆分

水平拆分

混合方案

读压力分摊

多从

nosql/cache

并且采用多级分层方案 

大数据量,并且进行分库分表后,不建议的SQL

复杂连接查询

跨库、跨表查询

分布式事务

子查询

涉及到跨库跨表查询时,通常需要好的中间层来解决

这个中间层大多靠自主开发,很少有现成的通用方案

跨表JOIN代价较高时,甚至可以考虑反范式,把多列存放在一个冗余表中,更方便查询 

如何应对瞬间暴增的业务压力 

快速响应,但延迟服务

前端利用CDN、缓存、静态内容抗住第一道访问

前端页面/APP端/转发层,增加刷新频率控制

动态请求需要有流控

业务隔离

区分不同业务所在资源池

重点业务,重点保障

弹性资源池(云) 

秒杀业务 

面临问题:高并发、超卖

前端提前准备措施:静态化、扩容、限流、服务降级机制

后端:限制MySQL的并发线程(并启用thread pool)、订单提交时再次判断,是否还有库存,可以直接使用AliSQL分支版本(应对秒杀场景特别有效)

提前把商品分摊到多个Redis实例中,根据用户ID哈希分配到各实例 

Redis中保存2个队列,一个被秒的,一个待秒的

还有个队列保存已经参加过秒杀的用户列表

秒杀成功后,被秒队列+1,待秒队列-1,加入已秒用户列表

读取已秒队列及已秒用户列表,更新到MySQL中

重点:入口请求有序排队避免蜂拥,合并写请求减小写压力

互联网常用高可用架构方案

分库分表

架构案例

分库分表

NOSQL、NEWSQL对MySQL的影响

无论NOSQL还是NEWSQL,都不能很好支持事务原子性

NOSQL更多的是cache作用

简单的KV数据,可以用innodb memcached plugin解决

复杂的文档数据,可以用JSON数据类型解决

NOSQL由于弱关系约束,后期反倒可能是灾难

NEWSQL主要解决数据分布式存储

真正需要存储海量数据时,更多的是考虑用大数据解决方案 

数据库安全 

防止SQL注入

SQLmap

BSQL Hacker

Havij

Safe3 SQL Injector

防止长时间运行的SQL

及时干掉

启用timeout