1.数据库:分片
分片解决的是“数据量太大”的问题,也就是通常说的“水平切分”。
分片路由规则通常有3种方法:
(1)范围:range
优点:简单,容易扩展
缺点:各库压力不均(新号段更活跃)
(2)哈希:hash (常用)
优点:简单,数据均衡,负载均匀
缺点:迁移麻烦(2库扩3库数据要迁移)
(3)路由服务:router-config-server
优点:灵活性强,业务与路由算法解耦
缺点:每次访问数据库前多一次查询
2.数据库:分组
为了解决“可用性”问题,数据库已经进行分组,分组通常通过主从复制的方式实现。
互联网公司实际的数据库架构是:分片 + 分组。
3.数据库:分表
如果单表的数据量很大的情况下,可以进行分表。分表的规则是ID哈希取余。
总结:分库可以增加数据库的IO, 分表不能。
问题根源:
DB主从同步有一定的时间差,在这个时间差内有读请求落到从库上,就会产生主从数据不一致的问题。
1.半同步
就是等主从同步完成之后,主库上的写请求再返回成功。
优点:利用数据库原生功能,实现简单。
缺点:主库的写请求时延会增大,吞吐量降低。
2.强制读主库
优点:读写直接操作主库,不存在一致性的问题。
缺点:只能通过cache来提升系统的都性能,需要进行系统改造。
3.数据库中间件
(1)所有的读写都走数据库中间件,通常情况下,写请求路由到主库,读请求路由到从库。
(2)记录所有路由到写库的key,在经验主从同步时间窗口内(假设是500ms),如果有读请求访问中间件,此时有可能从库还是旧数据,就把这个key上的读请求路由到主库。
(3)经验主从同步时间过完后,对应key的读请求继续路由到从库。
优点:能保证绝对一致。
缺点:数据库中间件的成本比较高。
4.缓存记录写key法
(1)将某个库上的某个key要发生写操作,记录在cache里,并设置“经验主从同步时间”的cache超时时间,例如500ms。
(2)再修改数据库。
当读请求发生时:
(1)先到cache里查看,对应库的对应key有没有相关数据。
(2)如果cache hit,有相关数据,说明这个key上刚发生过写操作,此时需要将请求路由到主库读最新的数据。
(3)如果cache miss,说明这个key上近期没有发生过写操作,此时将请求路由到从库,继续读写分离。
优点:相对数据库中间件,成本较低。
缺点:为了保证“一致性”,引入了一个cache组件,增加一次cache操作。