mysql数据库分片
1、amoeba相当于一个SQL请求的路由器,目的是为负载均衡、读写分离、高可用性提供机制,而不是完全实现它们。用户需要结合使用MySQL的Replication等机制来实现副本同步等功能。amoeba对底层数据库连接管理和路由实现也采用了可插拨的机制,第三方可以开发更高级的策略类来替代作者的实现。这个程序总体上比较符合KISS的思想。
2、由上一条,建议使用MySQL的Replication机制建立Master-Slave来做副本。我一开始理解有误,使用了amoeba的virtual DB(负载均衡pool)做writePool,结果使得本应插入同一个表中的数据被拆分地写入了不同的物理数据库中。这样自然与副本的语义不符了。
3、amoeba已经实现了数据的垂直切分与水平切分。水平切分方面,粒度是行。使用SQLJEP语句可以设计出复杂的切分规则,个人认为是比较强大的。垂直切分的粒度是表,可以把针对不同表的请求发送到不同的节点上执行,但不能以列作为分片粒度。从作者的说法看,amoeba不做SQL解析和重写。在目前的机制下似乎是难以实现同一个表不同的列在不同节点上的分布。不过对开发人员来说,设计良好的表结构应该可以实现简单的基于关系属性的负载均衡的。
❷ 骞茶揣婊℃弧锛氩熀浜岙hardingSphere瀹炵幇锷ㄦ佹暟鎹婧
鍦ㄤ簰镵旂绣鍏鍙镐腑锛屾垨钥呭ぇ鍨嫔簲鐢ㄧ郴缁熶腑锛屾垜浠浣滀负寮鍙戜汉锻橀氩父闇瑕侀溃瀵规捣閲忕殑鏁版嵁锛岃繖浜涙捣閲忔暟鎹阃氩父閮芥槸锏句竾绾э纴鍗冧竾绾х殑鏁版嵁閲忋傝屼笖杩欎簺娴烽噺鏁版嵁瀵逛紒涓氩拰鐢ㄦ埛𨱒ヨ撮兘鏄镊冲叧閲嶈佺殑銆傞溃瀵瑰傛ゆ捣閲忕殑鏁版嵁锛屾垜浠闇瑕佷缭璇佹暟鎹镄勫畨鍏ㄥ彲闱狅绂褰扑缭瀛樻暟鎹镄勬椂鍊欐暟鎹涓嶈兘涓㈠け锛屽綋镆ヨ㈡暟鎹镄勬椂鍊欙纴闇瑕佷缭璇佹暟鎹镄勫强镞跺搷搴斻
闾d箞锛屽备綍淇濊瘉杩欎簺娴烽噺鏁版嵁镄勫畨鍏ㄥ彲闱狅纴浠ュ强瀹炴椂镆ヨ㈠憿锛
褰撶劧锛岃繖閲岃偗瀹氢细链夊緢澶氲В鍐虫柟妗堛傚湪褰扑笅澶ф暟鎹镞朵唬锛屽嚭鐜颁简寰埚氭瘆杈冨弸濂界殑瑙e喅鏂规埚拰妗嗘灦鍙浠ヨВ鍐宠繖涓闂棰樸备緥濡傦细Elasticsearch锛孒adoop绛夛纴閮芥槸鐜板湪姣旇缉娴佽岀殑妗嗘灦銆
鐩鍓嶏纴澶у氭暟浼佷笟搴旂敤绯荤粺涓镄勬暟鎹搴旇ラ兘鏄缁撴瀯鍖栫殑锛屼篃灏辨槸杩欎簺娴烽噺鏁版嵁瀛桦偍鍦ㄥ叧绯诲瀷鏁版嵁搴扑腑锛屼緥濡傦细Mysql锛孙racle绛夈傝屼笖Mysql鍏崇郴鍨嬫暟鎹搴扑竴鑸閮芥槸鍒濆垱浼佷笟鎴栬呬腑灏忎紒涓氱殑棣栭夈傞偅涔圡ysql濡备綍镓胯浇锏句竾绾э纴鍗冧竾绾х殑鏁版嵁锻锛熸牴鎹阒块噷宸村反镄勫紑鍙戝畧鍒欙纴寤鸿甅ysql镄勬暟鎹琛ㄥ归噺涓嶈佽秴杩500涓囨浔鏁版嵁璁板綍锛屼篃灏辫村缓璁鍦500涓囨浔鏁版嵁璁板綍镄勬椂鍊椤仛涓娆″垎琛ㄣ傞拡瀵筂ysql镄勫垎搴揿垎琛ㄥ凡缁忓瓨鍦ㄥ緢澶氭垚镡燂纴寮婧愮殑瑙e喅鏂规埚拰妗嗘灦锛屼緥濡傦细Mycat锛孲hardingSphere绛夈
浣嗘槸锛屽湪澶у氭暟涓氩姟鍦烘櫙涓璏ysql镄勪竴涓搴扑细链夊緢澶氲〃锛屾暟鎹閲忓ぇ镄勶纴闇瑕佸强镞跺搷搴旀煡璇㈢殑鏁版嵁琛ㄥ彲鑳藉氨闾d箞鍑犲紶锛屼緥濡傦细璁㈠崟琛ㄦ暟鎹閲忔瘆杈冨ぇ锛岄厤缃琛ㄦ暟鎹閲忔瘆杈冨皬锛涙垜浠闇瑕佸规暟鎹閲忔瘆杈冨ぇ镄勮㈠崟琛ㄨ繘琛屽垎搴揿垎琛ㄦ搷浣滐纴閰岖疆琛ㄥ彲浠ヤ笉闇瑕佸垎搴揿垎琛ㄣ备篃灏辨槸璇存垜浠闇瑕佸归儴鍒呜〃杩涜屽垎搴揿垎琛锛岄儴鍒呜〃涓嶈繘琛屽垎搴揿垎琛ㄣ傞偅涔堟垜浠鍙浠ヨ冭槛浣跨敤ShardingSphere镄勫姩镐佹暟鎹婧愶纴瀵归渶瑕佸垎搴揿垎琛ㄧ殑鏁版嵁鎴戜滑鎶婃g‘镄勬暟鎹婧愯矾鐢卞埌姝g‘镄勫簱涓婏纴鎶娄笉闇瑕佸垎搴揿垎琛ㄧ殑琛ㄨ矾鐢卞埌榛樿ょ殑鏁版嵁搴撱
涓嬮溃鎴戜滑浠SpringBoot涓轰緥鎶婅︾粏镄勫疄璺佃繃绋嬭板綍涓嬫潵锛屾柟渚夸互钖庢煡阒呫
寮曞叆ShardingSphere镄刴aven dependency锛岄噰鐢4.0.0鐗堟湰
閰岖疆澶氭暟鎹婧
璇存槑濡备笅锛
澶氭暟鎹婧愰厤缃绫
璇存槑濡备笅锛
涓嬮溃閰岖疆SpringBoot镄勬暟鎹婧
璇存槑濡备笅锛
涓嬮溃鏄鎴戜滑镊瀹氢箟镄勫垎鐗囩畻娉旵ustomShardingAlgorithm绫
璇存槑濡备笅锛
阃氲繃浠ヤ笂閰岖疆鍜岃嚜瀹氢箟鍒嗙墖绠楁硶锛屽熷姪ShardingSphere妗嗘灦鎴戜滑宸茬粡瀹炵幇浜嗛氲繃鎼哄甫鍒嗙墖阌镄勫炲垹鏀规煡sql璇鍙ュ姩镐佽矾鐢辨暟鎹婧愩傚傛灉镎崭綔鎴戜滑闇瑕佸垎搴揿垎琛ㄧ殑sql璇鍙ユ病鐢ㄦ恶甯﹀垎鐗囬敭锛孲hardingSphere浼氭姤阌椤苟涓斿湪镞ュ织淇℃伅涓浼氱湅鍒板瑰簲镄勯敊璇淇℃伅銆
褰撶劧闄よ繃ShardingSphere鑳藉熷疄鐜板姩镐佹暟鎹婧愶纴鍏朵粬妗嗘灦鎴栬呮柟寮忎篃鍙浠ュ疄鐜帮纴渚嫔傦细Spring AOP鍒囬溃锛屾嫤鎴鍣ㄤ篃鍙浠ュ疄鐜般傞偅涔埚氨鏄浠佽呰佷粊锛屾櫤钥呰佹櫤浜嗐
鍙傝冭祫鏂欙细
❸ 数据库为什么要分库分表
1 基本思想之什么是分库分表?
从字面上简单理解,就是把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上。
2 基本思想之为什么要分库分表?
数
据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作,增
删改查的开销也会越来越大;另外,由于无法进行分布式式部署,而一台服务器的资源(CPU、磁盘、内存、IO等)是有限的,最终数据库所能承载的数据量、
数据处理能力都将遭遇瓶颈。
3 分库分表的实施策略。
分库分表有垂直切分和水平切分两种。
3.1
何谓垂直切分,即将表按照功能模块、关系密切程度划分出来,部署到不同的库上。例如,我们会建立定义数据库workDB、商品数据库payDB、用户数据
库userDB、日志数据库logDB等,分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。
3.2
何谓水平切分,当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,例如userID散列,进行划分,然后存储到多个结构相同的表,和不同的库
上。例如,我们的userDB中的用户数据表中,每一个表的数据量都很大,就可以把userDB切分为结构相同的多个userDB:part0DB、
part1DB等,再将userDB上的用户数据表userTable,切分为很多userTable:userTable0、userTable1等,
然后将这些表按照一定的规则存储到多个userDB上。
3.3 应该使用哪一种方式来实施数据库分库分表,这要看数据库中数据量的瓶颈所在,并综合项目的业务类型进行考虑。
如果数据库是因为表太多而造成海量数据,并且项目的各项业务逻辑划分清晰、低耦合,那么规则简单明了、容易实施的垂直切分必是首选。
而
如果数据库中的表并不多,但单表的数据量很大、或数据热度很高,这种情况之下就应该选择水平切分,水平切分比垂直切分要复杂一些,它将原本逻辑上属于一体
的数据进行了物理分割,除了在分割时要对分割的粒度做好评估,考虑数据平均和负载平均,后期也将对项目人员及应用程序产生额外的数据管理负担。
在现实项目中,往往是这两种情况兼而有之,这就需要做出权衡,甚至既需要垂直切分,又需要水平切分。我们的游戏项目便综合使用了垂直与水平切分,我们首先对数据库进行垂直切分,然后,再针对一部分表,通常是用户数据表,进行水平切分。
4 分库分表存在的问题。
4.1 事务问题。
在执行分库分表之后,由于数据存储到了不同的库上,数据库事务管理出现了困难。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。
4.2 跨库跨表的join问题。
在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,这时,表的关联操作将受到限制,我们无法join位于不同分库的表,也无法join分表粒度不同的表,结果原本一次查询能够完成的业务,可能需要多次查询才能完成。
4.3 额外的数据管理负担和数据运算压力。
额
外的数据管理负担,最显而易见的就是数据的定位问题和数据的增删改查的重复执行问题,这些都可以通过应用程序解决,但必然引起额外的逻辑运算,例如,对于
一个记录用户成绩的用户数据表userTable,业务要求查出成绩最好的100位,在进行分表之前,只需一个order
by语句就可以搞定,但是在进行分表之后,将需要n个order
by语句,分别查出每一个分表的前100名用户数据,然后再对这些数据进行合并计算,才能得出结果。
❹ 数据库架构选型与落地,看这篇就够了
随着时间和业务的发展,数据库中的数据量增长是不可控的,库和表中的数据会越来越大,随之带来的是更高的 磁盘 、 IO 、 系统开销 ,甚至 性能 上的瓶颈,而单台服务器的 资源终究是有限 的。
因此在面对业务扩张过程中,应用程序对数据库系统的 健壮性 , 安全性 , 扩展性 提出了更高的要求。
以下,我从数据库架构、选型与落地来让大家入门。
数据库会面临什么样的挑战呢?
业务刚开始我们只用单机数据库就够了,但随着业务增长,数据规模和用户规模上升,这个时候数据库会面临IO瓶颈、存储瓶颈、可用性、安全性问题。
为了解决上述的各种问题,数据库衍生了出不同的架构来解决不同的场景需求。
将数据库的写操作和读操作分离,主库接收写请求,使用多个从库副本负责读请求,从库和主库同步更新数据保持数据一致性,从库可以水平扩展,用于面对读请求的增加。
这个模式也就是常说的读写分离,针对的是小规模数据,而且存在大量读操作的场景。
因为主从的数据是相同的,一旦主库宕机的时候,从库可以 切换为主库提供写入 ,所以这个架构也可以提高数据库系统的 安全性 和 可用性 ;
优点:
缺点:
在数据库遇到 IO瓶颈 过程中,如果IO集中在某一块的业务中,这个时候可以考虑的就是垂直分库,将热点业务拆分出去,避免由 热点业务 的 密集IO请求 影响了其他正常业务,所以垂直分库也叫 业务分库 。
优点:
缺点:
在数据库遇到存储瓶颈的时候,由于数据量过大造成索引性能下降。
这个时候可以考虑将数据做水平拆分,针对数据量巨大的单张表,按照某种规则,切分到多张表里面去。
但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈(单个服务器的IO有上限)。
所以水平分表主要还是针对 数据量较大 ,整体业务 请求量较低 的场景。
优点:
缺点:
四、分库分表
在数据库遇到存储瓶颈和IO瓶颈的时候,数据量过大造成索引性能下降,加上同一时间需要处理大规模的业务请求,这个时候单库的IO上限会限制处理效率。
所以需要将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。
分库分表能够有效地缓解单机和单库的 性能瓶颈和压力 ,突破IO、连接数、硬件资源等的瓶颈。
优点:
缺点:
注:分库还是分表核心关键是有没有IO瓶颈 。
分片方式都有什么呢?
RANGE(范围分片)
将业务表中的某个 关键字段排序 后,按照顺序从0到10000一个表,10001到20000一个表。最常见的就是 按照时间切分 (月表、年表)。
比如将6个月前,甚至一年前的数据切出去放到另外的一张表,因为随着时间流逝,这些表的数据被查询的概率变小,银行的交易记录多数是采用这种方式。
优点:
缺点:
HASH(哈希分片)
将订单作为主表,然后将其相关的业务表作为附表,取用户id然后 hash取模 ,分配到不同的数据表或者数据库上。
优点:
缺点:
讲到这里,我们已经知道数据库有哪些架构,解决的是哪些问题,因此, 我们在日常设计中需要根据数据的特点,数据的倾向性,数据的安全性等来选择不同的架构 。
那么,我们应该如何选择数据库架构呢?
虽然把上面的架构全部组合在一起可以形成一个强大的高可用,高负载的数据库系统,但是架构选择合适才是最重要的。
混合架构虽然能够解决所有的场景的问题,但是也会面临更多的挑战,你以为的完美架构,背后其实有着更多的坑。
1、对事务支持
分库分表后(无论是垂直还是水平拆分),就成了分布式事务了,如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价(XA事务);如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担(TCC、SAGA)。
2、多库结果集合并 (group by,order by)
由于数据分布于不同的数据库中,无法直接对其做分页、分组、排序等操作,一般应对这种多库结果集合并的查询业务都需要采用数据清洗、同步等其他手段处理(TIDB、KUDU等)。
3、数据延迟
主从架构下的多副本机制和水平分库后的聚合库都会存在主数据和副本数据之间的延迟问题。
4、跨库join
分库分表后表之间的关联操作将受到限制,我们无法join位于不同分库的表(垂直),也无法join分表粒度不同的表(水平), 结果原本一次查询就能够完成的业务,可能需要多次查询才能完成。
5、分片扩容
水平分片之后,一旦需要做扩容时。需要将对应的数据做一次迁移,成本代价都极高的。
6、ID生成
分库分表后由于数据库独立,原有的基于数据库自增ID将无法再使用,这个时候需要采用其他外部的ID生成方案。
一、应用层依赖类(JDBC)
这类分库分表中间件的特点就是和应用强耦合,需要应用显示依赖相应的jar包(以Java为例),比如知名的TDDL、当当开源的 sharding-jdbc 、蘑菇街的TSharding等。
此类中间件的基本思路就是重新实现JDBC的API,通过重新实现 DataSource 、 PrepareStatement 等操作数据库的接口,让应用层在 基本 不改变业务代码的情况下透明地实现分库分表的能力。
中间件给上层应用提供熟悉的JDBC API,内部通过 sql解析 、 sql重写 、 sql路由 等一系列的准备工作获取真正可执行的sql,然后底层再按照传统的方法(比如数据库连接池)获取物理连接来执行sql,最后把数据 结果合并 处理成ResultSet返回给应用层。
优点
缺点
二、中间层代理类(Proxy)
这类分库分表中间件的核心原理是在应用和数据库的连接之间搭起一个 代理层 ,上层应用以 标准的MySQL协议 来连接代理层,然后代理层负责 转发请求 到底层的MySQL物理实例,这种方式对应用只有一个要求,就是只要用MySQL协议来通信即可。
所以用MySQL Navicat这种纯的客户端都可以直接连接你的分布式数据库,自然也天然 支持所有的编程语言 。
在技术实现上除了和应用层依赖类中间件基本相似外,代理类的分库分表产品必须实现标准的MySQL协议,某种意义上讲数据库代理层转发的就是MySQL协议请求,就像Nginx转发的是Http协议请求。
比较有代表性的产品有开创性质的Amoeba、阿里开源的Cobar、社区发展比较好的 Mycat (基于Cobar开发)等。
优点
缺点
JDBC方案 :无中心化架构,兼容市面上大多数关系型数据库,适用于开发高性能的轻量级 OLTP 应用(面向前台)。
Proxy方案 :提供静态入口以及异构语言的支持,适用于 OLAP 应用(面向后台)以及对分片数据库进行管理和运维的场景。
混合方案 :在大型复杂系统中存在面向C端用户的前台应用,也有面向企业分析的后台应用,这个时候就可以采用混合模式。
JDBC 采用无中心化架构,适用于 Java 开发的高性能的轻量级 OLTP 应用;Proxy 提供静态入口以及异构语言的支持,适用于 OLAP 应用以及对分片数据库进行管理和运维的场景。
ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 Sharding-JDBC 、 Sharding-Proxy 和 Sharding-Sidecar (计划中)这3款相互独立的产品组成,他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。
ShardingSphere提供的核心功能:
Sharding-Proxy
定位为透明化的 数据库代理端 ,提供封装了 数据库二进制协议的服务端版本 ,用于完成对 异构语言的支持 。
目前已提供MySQL版本,它可以使用 任何兼容MySQL协议的访问客户端 (如:MySQL Command Client, MySQL Workbench, Navicat等)操作数据,对DBA更加友好。
向 应用程序完全透明 ,可直接当做MySQL使用。
适用于任何兼容MySQL协议的客户端。
Sharding-JDBC
定位为 轻量级Java框架 ,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为 增强版的JDBC驱动,完全兼容JDBC和各种ORM框架 。
以电商SaaS系统为例,前台应用采用Sharding-JDBC,根据业务场景的差异主要分为三种方案。
分库(用户)
问题解析:头部企业日活高并发高,单独分库避免干扰其他企业用户,用户数据的增长缓慢可以不分表。
拆分维度:企业ID分库
拆分策略:头部企业单独库、非头部企业一个库
分库分表(订单)
问题解析:订单数据增长速度较快,在分库之余需要分表。
拆分维度:企业ID分库、用户ID分表
拆分策略:头部企业单独库、非头部企业一个库,分库之后用户ID取模拆分表
单库分表(附件)
问题解析:附件数据特点是并发量不大,只需要解决数据增长问题,所以单库IO足以支撑的情况下分表即可。
拆分维度:用户ID分表
拆分策略:用户ID取模分表
问题一:分布式事务
分布式事务过于复杂也是分布式系统最难处理的问题,由于篇幅有限,后续会开篇专讲这一块内容。
问题二:分布式ID
问题三:跨片查询
举个例子,以用户id分片之后,需要根据企业id查询企业所有用户信息。
sharding针对跨片查询也是能够支持的,本质上sharding的跨片查询是采用同时查询多个分片的数据,然后聚合结果返回,这个方式对资源耗费比较大,特别是对数据库连接资源的消耗。
假设分4个数据库,8个表,则sharding会同时发出32个SQL去查询。一下子消耗掉了32个连接;
特别是针对单库分表的情况要注意,假设单库分64个表,则要消耗64个连接。如果我们部署了2个节点,这个时候两个节点同时查询的话,就会遇到数据库连接数上限问题(mysql默认100连接数)
问题四:分片扩容
随着数据增长,每个片区的数据也会达到瓶颈,这个时候需要将原有的分片数量进行增加。由于增加了片区,原先的hash规则也跟着变化,造成了需要将旧数据做迁移。
假设原先1个亿的数据,hash分64个表,现在增长到50亿的数据,需要扩容到128个表,一旦扩容就需要将这50亿的数据做一次迁移,迁移成本是无法想象的。
问题五:一致性哈希
首先,求出每个 服务器的hash值 ,将其配置到一个 0~2^n 的圆环上 (n通常取32)
其次,用同样的方法求出待 存储对象的主键 hash值 ,也将其配置到这个圆环上。
然后,从数据映射到的位置开始顺时针查找,将数据分布到找到的第一个服务器节点上。
一致性hash的优点在于加入和删除节点时只会影响到在哈希环中相邻的节点,而对其他节点没有影响。
所以使用一致性哈希在集群扩容过程中可以减少数据的迁移。
好了,这次分享到这里,我们日常的实践可能只会用到其中一种方案,但它不是数据库架构的全貌,打开技术视野,才能更好地把存储工具利用起来。
老规矩,一键三连,日入两千,点赞在看,年薪百万!
本文作者:Jensen
7年Java老兵,小米主题设计师,手机输入法设计师,ProcessOn特邀讲师。
曾涉猎航空、电信、IoT、垂直电商产品研发,现就职于某知名电商企业。
技术公众号 【架构师修行录】 号主,专注于分享日常架构、技术、职场干货,Java Goals:架构师。
交个朋友,一起成长!
❺ 如何在一台服务器上安装两个mysql或者更多
这种架构一般用在以下三类场景
1. 备份多台 Server 的数据到一台如果按照数据切分方向来讲,那就是垂直切分。比如图 2,业务 A、B、C、D 是之前拆分好的业务,现在需要把这些拆分好的业务汇总起来备份,那这种需求也很适用于多源复制架构。实现方法我大概描述下:业务 A、B、C、D 分别位于 4 台 Server,每台 Server 分别有一个数据库来隔离前端的业务数据,那这样,在从库就能把四台业务的数据全部汇总起来,而不需要做额外的操作。那没有多源复制之前,要实现这类需求,只能在汇总机器上搭建多个 MySQL 实例,那这样势必会涉及到跨库关联的问题,不但性能急剧下降,管理多个实例也没有单台来的容易。