读写分离
- 在主从同步正常时,解析sql语句,根据行为转发到主库写或者从库读
- 当主库宕掉后,以Proxy和MYSQL的心跳来判断,读写操作都会发到从库上
- 从库宕掉后,以Proxy和MYSQL的心跳来判断,读写操作都会发到主库上
分片
-
分片原则
- 与拆分表有关系的表一起分表,例如事务,业务关联
- 依据业务来分片,如果没有,才用主键分片
- 选择的业务字段,应该是最频繁的或者最重要的查询条件
- 选择的业务字段,应该能尽可能均匀的分布到所有的节点
-
水平拆分
- 多维拆分
如果我按照oid拆分,但是我现在查询语句只有uid,那么就会全表扫描
如果我按照uid拆分,但是我现在查询语句只有oid,那么也会全表扫描
那么我可以进行二维拆分,同时按照oid和uid进行拆分
此时如果我的查询条件既有oid又有uid,那么我很容易找到我需要的数据
如果查询条件只有oid,那么就会扫描带有oid的那一个系列
同理,如果查询条件只有uid,那么就会扫描带有uid的那一个系列
拆分问题
- 分多少片合适?
- 路由算法怎么选择?
- 数据增长以后如果迁移
- 有没有热点问题
路由算法
- 枚举(能够穷举),春夏秋冬
- 固定hash(通用固定hash算法),hashcode % 16
- 范围,[0,100),[100,500),[500,20000),[20000,∞)
- 日期列(数据时间特征明显),银行账单
- 一致性hash,实质是一种特殊的范围hash
一致性hash
- 固定哈希算法足够简单实用,根据数据特点能够均匀分布,但是在数据库扩容的时候,固定哈希算法迁移非常复杂,由于取模的结果变化,绝大部分数据都要进行迁移,当数据库倍增的时候,数据迁移最少,但也高达 50%,而且倍增的成本比较高。
- 一致性hash的原理就是通过该算法计算出 key 的 hashcode 之后进行 2^32 取模,那么数据就会落在 0~2^32 所组成的环中;然后对现在提供的节点进行范围分配,假设我有8个节点,将0~2^32的范围均分到每个节点,然后根据取模之后的值计算落到哪个节点。好处是现在我发现第5号节点压力过大,我想加一个节点,那么我只需要将5号节点的范围缩小一半,然后使用新加入的节点负责另一半,此时只需要迁移5号节点的另一半数据,如果数据分布均匀,迁移的数据就只有16分之一
- 虚拟节点,有时候会出现热点问题,一致性哈希并不能解决。所以可以引入虚拟节点的概念,它是物理节点的映射,一个物理节点可以复制出多个虚拟节点,尽可能的让它均匀分布在环上,那么即使数据再集中,其实也会存储在不同的节点上,可以起到负载均衡的作用。