当前位置:首页 > 生态圈 > 正文内容

分库分表具体实现(分库分表的区别)

abcsky883个月前 (02-08)生态圈61

今天给各位分享

分库分表,是企业里面毕竟常见的针对高并发、数据量大的场景下的一种技术优化方案,也是一个非常高频的面试题但是,因为很多人其实并没有非常丰富的分库分表的经验,所以能把这个问题回答的比较好的人其实还挺少的那么,本文就来试图把关于分库分表的事情,一次性的讲个清楚。

分库分表具体实现(分库分表的区别)

分库,分表,分库分表首先,我们需要知道所谓"分库分表",根本就不是一件事儿,而是三件事儿,他们要解决的问题也都不一样这三个事儿分别是"只分库不分表"、"只分表不分库"、以及"既分库又分表"什么时候分库?。

其实,分库主要解决的是并发量大的问题因为并发量一旦上来了,那么数据库就可能会成为瓶颈,因为数据库的连接数是有限的,虽然可以调整seo收录查询,但是也不是无限调整的所以,当当你的数据库的读或者写的QPS过高,导致你的数据库连接数不足了的时候,就需要考虑分库了,。

通过增加数据库实例的方式来提供更多的可用数据库链接,从而提升系统的并发度比较典型的分库的场景就是我们在做微服务拆分的时候,就会按照业务边界,把各个业务的数据从一个单一的数据库中拆分开,分表把订单、物流、商品、会员等单独放到单独的数据库中。

还有就是有的时候可能会需要把历史订单挪到历史库里面去这也是分库的一种具体做法什么时候分表?分库主要解决的是并发量大的问题,那分表其实主要解决的是数据量大的问题假如你的单表数据量非常大,因为并发不高,数据量连接可能还够,但是存储和查询的性能遇到seo收录查询了瓶颈了,你做了很多优化之后还是无法提升效率的时候,就需要考虑做分表了。

通过将数据拆分到多张表中,来减少单表的数据量,从而提升查询速度一般我们认为,单表行数超过 500 万行或者单表容量超过 2GB之后,才需要考虑做分库分表了,小于这个数据量,遇到性能问题先建议大家通过其他优化来解决。

什么时候既分库又分表?那么什么时候分库又分表呢,那就是既需要解决并发量大的问题,又需要解决数据量大的问题时候通常情况下,高并发和数据量大的问题都是同时发生的,所以,我们会经常遇到分库分表需要同时进行的情况。

所以,当你的数据库链接也不够了,并且单表数据量也很大导致查询比较慢的时候,就需要做既分库又分表了横向拆分和纵seo收录查询向拆分谈及到分库分表,那就要涉及到该如何做拆分的问题通常在做拆分的时候有两种分法,分别是横向拆分(水平拆分)和纵向拆分(垂直拆分)。

假如我们有一张表,如果把这张表中某一条记录的多个字段,拆分到多张表中,这种就是纵向拆分那如果把一张表中的不同的记录分别放到不同的表中,这种就是横向拆分横向拆分的结果是数据库表中的数据会分散到多张分表中,使得每一个单表中的数据的条数都有所下降。

比如我们可以把不同的用户的订单分表拆分放到不同的表中

纵向拆分的结果是数据库表中的数据的字段数会变少,使得每一个单表中的数据的存储有所下降。比如我可以把商品详情信息、价格信息、库存信息等等分别拆分到不同的表中。

还有我们谈到的针对seo收录查询不同的业务做拆分成多个数据库的这种情况,其实也是纵向拆分的一种分表字段的选择在分库分表的过程中,我们需要有一个字段用来进行分表,比如按照用户分表、按照时间分表、按照地区分表这里面的用户、时间、地区就是所谓的分表字段。

那么,在选择这个分表字段的时候,一定要注意,要根据实际的业务情况来做慎重的选择比如说我们要对交易订单进行分表的时候,我们可以选择的信息有很多,比如买家Id、卖家Id、订单号、时间、地区等等,具体应该如何选择呢?。

通常,如果有特殊的诉求,比如按照月度汇总、地区汇总等以外,我们通常建议大家按照买家Id进行分表因为这样可以避免一个关键的问题那就是——数据倾斜(热点数据)买家还是卖家?首先seo收录查询,我们先说为什么不按照卖家分表?。

因为我们知道,电商网站上面是有很多买家和卖家的,但是,一个大的卖家可能会产生很多订单,比如像苏宁易购、当当等这种店铺,他每天在天猫产生的订单量就非常的大如果按照卖家Id分表的话,那同一个卖家的很多订单都会分到同一张表。

那就会使得有一些表的数据量非常的大,但是有些表的数据量又很小,这就是发生了数据倾斜。这个卖家的数据就变成了热点数据,随着时间的增长,就会使得这个卖家的所有操作都变得异常缓慢。

但是,买家ID做分表字段就不会出现这类问题,因为一个不太容易出现一个买家能把数据买倾斜了但是需要注意的是,我们说按照买家Id做分表,保证的是同一个买家的所有订单都在同一张表 seo收录查询,并不是要给每个买家都单独分配一张表。

我们在做分表路由的时候,是可以设定一定的规则的,比如我们想要分1024张表,那么我们可以用买家ID或者买家ID的hashcode对1024取模,结果是0000-1023,那么就存储到对应的编号的分表中就行了。

卖家查询怎么办?如果按照买家Id进行了分表,那卖家的查询怎么办,这不就意味着要跨表查询了吗?首先,业务问题我们要建立在业务背景下讨论电商网站订单查询有几种场景?1、买家查自己的订单2、卖家查自己的订单3、平台的小二查用户的订单。

首先,我们用买家ID做了分表,那么买家来查询的时候,是一定可以把买家ID带过来的,我们直接去对应的表里面查询就行了那如果是卖家seo收录查询查呢?卖家查询的话,同样可以带卖家id过来,那么,我们可以有一个基于binlog、flink等准实时的同步一张卖家维度的分表,这张表只用来查询,来解决卖家查询的问题。

本质上就是用空间换时间的做法不知道大家看到这里会不会有这样的疑问:同步一张卖家表,这不又带来了大卖家的热点问题了吗?首先,我们说同步一张卖家维度的表来,但是其实所有的写操作还是要写到买家表的,只不过需要准实时同步的方案同步到卖家表中。

也就是说,我们的这个卖家表理论上是没有业务的写操作,只有读操作的所以,这个卖家库只需要有高性能的读就行了,那这样的话就可以有很多选择了,比如可以部署到一些配置不用那么高的机器、或者其实可以干脆就不用Mseo收录查询YSQL,而是采用HBASE、PolarDB、Lindorm等数据库就可以了。

这些数据库都是可以海量数据,并提供高性能查询的还有呢就是,大卖家一般都是可以识别的,提前针对大卖家,把他的订单,再按照一定的规则拆分到多张表中因为只有读,没有写操作,所以拆分多张表也不用考虑事务的问题按照订单查询怎么办

?上面说的都是有买卖家ID的情况,那没有买卖家ID呢?用订单号直接查怎么办呢?这种问题的解决方案是,在生成订单号的时候,我们一般会把分表解决编码到订单号中去,因为订单生成的时候是一定可以知道买家ID的,那么我们就把买家ID的路由结果比如1023,作为一段固定的值放到订单号中就行了。

这就是所谓的"基因法"seo收录查询这样按照订单号查询的时候,解析出这段数字,直接去对应分表查询就好了至于还有人问其他的查询,没有买卖家ID,也没订单号的,那其实就属于是低频查询或者非核心功能查询了,那就可以用ES等搜索引擎的方案来解决了。

就不赘述了分表算法选定了分表字段之后,如何基于这个分表字段来准确的把数据分表到某一张表中呢?这就是分表算法要做的事情了,但是不管什么算法,我们都需要确保一个前提,那就是同一个分表字段,经过这个算法处理后,得到的结果一定是一致的,不可变的。

通常情况下,当我们对order表进行分表的时候,比如我们要分成128张表的话,那么得到的128表应该是:order_0000、order_0001、orderseo收录查询_0002.....order_0126、order_0127

通常的分表算法有以下几种:直接取模在分库分表时,我们是事先可以知道要分成多少个库和多少张表的,所以,比较简单的就是取模的方式比如我们要分成128张表的话,就用一个整数来对128取模就行了,得到的结果如果是0002,那么就把数据放到order_0002这张表中。

Hash取模那如果分表字段不是数字类型,而是字符串类型怎么办呢?有一个办法就是哈希取模,就是先对这个分表字段取Hash,然后在再取模但是需要注意的是,Java中的hash方法得到的结果有可能是负数,需要考虑这种负数的情况。

一致性Hash前面两种取模方式都比较不错,可以使我们的数seo收录查询据比较均匀的分布到多张分表中但是还是存在一个缺点那就是如果需要扩容二次分表,表的总数量发生变化时,就需要重新计算hash值,就需要涉及到数据迁移了。

为了解决扩容的问题,我们可以采用一致性哈希的方式来做分表。

一致性哈希可以按照常用的hash算法来将对应的key哈希到一个具有2^32次方个节点的空间中,形成成一个顺时针首尾相接的闭合的环形所以当添加一台新的数据库服务器时,只有增加服务器的位置和逆时针方向第一台服务器之间的键会受影响。

全局ID的生成涉及到分库分表,就会引申出分布式系统中唯一主键ID的生成问题,因为在单表中我们可以用数据库主键来做唯一ID,但是如果做了分库分表,多张单表中的自增主键就一seo收录查询定会发生冲突那就不具备全局唯一性了。

那么,如何生成一个全局唯一的ID呢?有以下几种方式:UUID很多人对UUID都不陌生,它是可以做到全局唯一的,而且生成方式也简单,但是我们通常不推荐使用他做唯一ID,首先UUID太长了,其次字符串的查询效率也比较慢,而且没有业务含义,根本看不懂。

基于某个单表做自增主键多张单表生成的自增主键会冲突,但是如果所有的表中的主键都从同一张表生成是不是就可以了所有的表在需要主键的时候,都到这张表中获取一个自增的ID这样做是可以做到唯一,也能实现自增,但是问题是这个单表就变成整个系统的瓶颈,而且也存在单点问题,一旦他挂了,那整个数据库就都无法写入了。

基于多个单表+步长做seo收录查询自增主键为了解决单个数据库做自曾主键的瓶颈及单点故障问题,我们可以引入多个表来一起生成就行了但是如何保证多张表里面生成的Id不重复呢?如果我们能实现以下的生成方式就行了:实例1生成的ID从1000开始,到1999结束。

实例2生成的ID从2000开始,到2999结束。实例3生成的ID从3000开始,到3999结束。实例4生成的ID从4000开始,到4999结束。

这样就能避免ID重复了,那如果第一个实例的ID已经用到1999了怎么办?那就生成一个新的起始值:实例1生成的ID从5000开始,到5999结束实例2生成的ID从6000开始,到6999结束实例3生成的ID从7000开始,到7999结束。

seo收录查询例4生成的ID从8000开始,到8999结束我们把步长设置为1000,确保每一个单表中的主键起始值都不一样,并且比当前的最大值相差1000就行了雪花算法雪花算法也是比较常用的一种分布式ID的生成方式,它具有全局唯一、递增、高可用的特点。

雪花算法生成的主键主要由 4 部分组成,1bit符号位、41bit时间戳位、10bit工作进程位以及 12bit 序列号位时间戳占用41bit,精确到毫秒,总共可以容纳约69年的时间工作进程位占用10bit,其中高位5bit是数据中心ID,低位5bit是工作节点ID,做多可以容纳1024个节点。

序列号占用12bit,每个节点每毫秒0开始不断累加,最多可以累加到4seo收录查询095,一共可以产生4096个ID所以,一个雪花算法可以在同一毫秒内最多可以生成1024 X 4096 = 4194304个唯一的ID。

分库分表的工具在选定了分表字段和分表算法之后,那么,如何把这些功能给实现出来,需要怎么做呢?我们如何可以做到像处理单表一样处理分库分表的数据呢?这就需要用到一个分库分表的工具了目前市面上比较不错的分库分表的开源框架主要有三个,分别是sharding-jdbc、TDDL和Mycat。

Sharding-JDBC现在叫ShardingSphere(Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar这3款相互独立的产品组成)它定seo收录查询位为轻量级Java框架,在Java的JDBC层提供的额外服务。

它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架开原地址:https://shardingsphere.apache.org

TDDLTDDL 是淘宝开源的一个用于访问数据库的中间件, 它集成了分库分表, 读写分离,权重调配,动态数据源配置等功能封装 jdbc 的 DataSource给用户提供统一的基于客户端的使用开源地址:https://github.com/alibaba/tb_tddl。

MycatMycat是一款分布式关系型数据库中间件它支持分布seo收录查询式SQL查询,兼容MySQL通信协议,以Java生态支持多种后端数据库,通过数据分片提高数据查询处理能力开源地址:https://github.com/MyCATApache/Mycat2。

分库分表带来的问题分库分表之后,会带来很多问题首先,做了分库分表之后,所有的读和写操作,都需要带着分表字段,这样才能知道具体去哪个库、哪张表中去查询数据如果不带的话,就得支持全表扫描但是,单表的时候全表扫描比较容易,但是做了分库分表之后,就没办法做扫表的操作了,如果要扫表的话就要把所有的物理表都要扫一遍。

还有,一旦我们要从多个数据库中查询或者写入数据,就有很多事情都不能做了,比如跨库事务就是不支持的。

所以,seo收录查询分库分表之后就会带来因为不支持事务而导致的数据一致性的问题其次,做了分库分表之后,以前单表中很方便的分页查询、排序等等操作就都失效了因为我们不能跨多表进行分页、排序总之,分库分表虽然能解决一些大数据量、高并发的问题,但是同时也会带来一些新的问题。

所以,在做数据库优化的时候,还是建议大家优先选择其他的优化方式,最后再考虑分库分表总结以上,本文介绍了分库分表的一些原因,以及如何做分库分表,并且讨论了其中比较关键的分表字段和分表算法的问题还介绍了几款比较不错的分库分表的相关框架。

最后,还有一些需要大家注意的就是分库分表会引入一些新的问题,这些问题的解决成本也都不低,所以在做技术选型的时候也要做好这方seo收录查询面的评估。

扫描二维码推送至手机访问。

版权声明:本文由海南拓宏网络科技工作室发布,如需转载请注明出处。

本文链接:http://4blc.com/post/15761.html

分享给朋友:

“分库分表具体实现(分库分表的区别)” 的相关文章

java语言和c语言的相同(java和c语言联系大吗)

本文分享给大家的是: Java和C语言是两种不同的编程语言,它们有许多不同之处,同时也有一些共同之处首先,C语言是一种编译型语言,而Java是一种解释型语言这意味着,在编写C程序时,源代码需要先被编译成机器码,然后才能被计算机执行;而Java程序则直接被Java虚拟机(JVM)解释...

计算机科学与技术考研考专业课哪些科目(计算机科学与技术考研考什么科目)

本文分享给大家的是: 原标题:计算机科学与技术专业考研有哪些科目?24考研鹅看过来计算机科学与技术,是一门普通高等学校本科专业,也是一个计算机系统与网络兼顾的计算机学科宽口径专业,属于计算机类专业,基本修业年限为四年,授予工学或理学学士学位。 如果想考研,计算机科学与技术专...

java和大数据哪个工资高(java好还是大数据好)

本篇文章给大家谈谈 单单提起java或者大数据,很多人对此都一目了然,但对于Java大数据这样一个新鲜名词,多少有些疑惑。Java和Java大数据学习的内容是一样的吗?两者有什么区别呢? Java和Java大数据的关系? Java和Java大数据的关系Java作为一...

电动车以旧换新猫腻(旧换新电动车价格查询官网)

本文分享给大家的是: 进入2023年来,不少用户都准备将自己的旧电动车通过“以旧换新”的方式更换新车但是在“以旧换新”时,很多用户都不清楚具体车型价格,害怕自己吃亏那么,到底电动车“以旧换新”能值多少钱呢?下面通过不同车型分析来告诉大家真实价格。 首先,我们来看48V车型,...

学计算机学的什么东西(学计算机专业主要学什么)

本篇文章给大家谈谈 学计算机的啊,帮我修修电脑吧!学计算机的啊,就是当程序猿?学计算机的啊,帮我重装一下系统呗!学计算机的啊,能帮我找回QQ密码不?……学计算机相关专业,到底都学啥?将来能干啥?从小就对计算机感兴趣,该选哪个专业? 没有计算机基础,可以学计算机相关专业吗?计...

中工网是国企吗(中工网是啥)

本文分享给大家的是: 我们位于北京中轴线上,工人日报社内办公,鼓楼就在眼前,著名的南锣鼓巷、什刹海等近在咫尺如果你有实力、有梦想,欢迎加入我们!招聘岗位网评中心副总监(1名)【任职岗位】带领部门人员完成频道内容的日常维护、组织选题策划采写编审发布、栏目发展规划与执行等。...