为什么要分库的原因:1)很多时候接口性能慢都是数据库造成的,2)并发量比较大时,大量的数据库请求,会带来磁盘I/O的性能瓶颈,3)来越多,导致sql查询数据,即使走了索引也比较慢。
(资料图)
分库和分表是不同的两个概念,解决的问题也不同。
并发量很大,但数据量比较小,可以只分库,不分表。并发量不大,但数据量比较大,可以只分表,不分库。并发量很大,数据量也比较多时,既要分库,也要分表。分库垂直分库,针对一个系统的不同业务进行拆分,比如:用户拆到User库,文章拆到Novel库,拆分后放到不同的服务器上,在高并发一定程度能够给解决I/O链接数,硬件资源瓶颈等。
垂直分表,整体策略就是大表拆小表,基于表中字段拆分,将不常用的,数据较大的拆分到扩展表,一般针对几百列的大表进行拆分。
特点:
每个库/表的结构都不一样每个库/表的数据至少一列一样每个库/表的并集是全量数据优点:拆分后业务清晰,数据维护简单,按照业务放到不同的服务器中。
缺点:
单表数据量大时,写读压力大受业务影响,热门业务压力大,冷门业务造成资源浪费。比如我们常用的user表,由2部分主要的功能组成,用户和密码主要是用来鉴权用户,一部分是展示用户信息,这个表就可以拆分成2个表。
mysql> desc user;+----------------------+---------------------+------+-----+------------+----------------+| Field | Type | Null | Key | Default | Extra |+----------------------+---------------------+------+-----+------------+----------------+| user_id | int(4) | NO | PRI | NULL | auto_increment || user_name | varchar(16) | NO | MUL | NULL | || user_psw | varchar(50) | NO | | NULL | || user_status | tinyint(1) | NO | | 1 | || user_display | tinyint(4) | NO | | 1 | || user_nickname | varchar(50) | YES | MUL | NULL | || user_email | varchar(50) | NO | MUL | NULL | || user_qq | varchar(15) | YES | | NULL | || user_tel | varchar(18) | YES | MUL | NULL | || user_sex | int(1) | NO | | 1 | || user_birthday | date | NO | | 1991-10-24 | || user_head | varchar(200) | NO | | NULL | || user_sign | varchar(225) | NO | | NULL | || user_ticket_act | int(11) | NO | | 0 | || user_gold2 | decimal(12,3) | NO | | 0.000 | || user_gold2_frozen | int(11) | NO | | 0 | || user_ticket_rec | int(11) | NO | | 0 | || user_ischarge | tinyint(1) | NO | | 0 | || user_exp | int(4) | NO | | 0 | || user_browse | int(4) | NO | | 0 | || user_logintime | int(4) | NO | | 0 | || user_regtime | int(4) | NO | MUL | 0 | || user_regip | varchar(15) | NO | | 0.0.0.0 | || user_displaytime | int(4) | NO | | 0 | || user_nickname_before | text | YES | | NULL | || user_auth | tinyint(1) | NO | | 0 | || delete_time | int(11) | NO | | 0 | || refresh_token | varchar(50) | NO | | | || nation_code | int(10) unsigned | NO | | 86 | || credit | int(11) | NO | | 0 | || close_time | int(10) unsigned | NO | | 0 | || finance_id | int(11) | NO | | 0 | || user_underage_status | tinyint(1) | NO | | 0 | || attr_limit | varchar(20) | NO | | NULL | || identity | tinyint(3) unsigned | NO | | 1 | |+----------------------+---------------------+------+-----+------------+----------------+35 行于数据集 (0.08 秒)优点:
单库/表的数据减少,有利性能库/表结构相同,程序改动小缺点:
数据库扩容难度大,比如取模值变了水平拆分的好处在于使用一个业务场景的划分值,比如user_id进行取模进行分表,但是在后台管理数据的时候会遇到一个问题,数据聚合和保持一致性的问题,比如我们现在业务中的评论数据就很多,user_id对 128进行取模,再后台管理的时候,把数据再存储在MongoDB中一份做数据管理使用,所有的方法都会有优缺点的,看你怎么设计更符合业务场景。
根据10取模,数据1保存到节点上,数据2保存在节点2上,当节点数发生变化,分子发生了变化,需要同步旧数据的值。
一致性Hash算法是怎么解决节点上的存储不均的情况呢?
在节点上创建虚拟节点,让虚拟节点对应真实节点,让数据的存储尽量均衡,这样就解决了数据不均的情况。
当添加新节点时,在普通取模算法中会影响到其他数据,而在一致性Hash算法中,首先会停止服务,防止数据乱掉,先把属于新增节点D的数据迁移到D节点中,然后添加节点,放入环中,启动服务。
当移除节点时,首先停止服务,把D节点移除之后,根据顺时针原则,把属于D节点的数据迁移在节点A上,把D节点服务移除,启动服务,整个节点受到影响的只有D节点的数据,不会影响其他的服务节点。
中间件的范围比较笼统,我理解的中间件就是在数据处理流程里,加入了一层逻辑处理,用规定好的规则下发在下一个流程中,主要介绍Mysql的2种中间件,ShardingSphere(直连模式) 和 MyCat(代理模式)。
ShardingSphere:Jdbc直连,相当于增强JDBC包,对所有的数据库操作语句按照特定的要求分发到不同的库中,这部分操作在jdbc中直接完成了。MyCat:proxy代理,把sql发送给代理服务,代理服务去数据库完成相应的操作后再返回给web应用。关键词:
热门推荐
最新资讯