分库分表学习和思考

学习总结

写这篇文章主要想解一下自己在大数据量下写数据或者频繁写数据的疑问,工作或者和他人闲聊中一般遇到的大数据量写的场景其实不多,多是密集读的场景,或者大部分情况下的解决方案都比较不彻底,或者比较“脏”,维护起来比较烦心,于是不如就花时间把这个问题想一想。

分库分表的原因

分库分表是一个实施的方案,我们要做分库分表要解决的问题具体来说是:
要解决数据库写压力大的问题;
或者数据量大导致读写慢的问题;
或者是MySQL集群水平扩展问题;

解决这些问题的办法并不只有分库或者分表,数据量大的问题通过做冷热数据分离也是可以解决的;业务密集写导致机器负载高的问题也是可以通过产品同学和开发同学一起商量去解决的;数据量如果不是很大的情况下,通过垂直分表也是一个解决问题的办法,例如在业务或架构上解耦,不同服务读取该服务单独的库,或者单个服务内将大表分离为多个表,业务端分散写压力,自然也都是可以解决问题的。
这里我们只是来研究讨论一下水平扩展下的分库分表方案和设计。

分布算法设计/数据分布设计

我们接下来遇到的问题是我们要怎么设计我们的数据分布,分库、分表、分区都是分散数据分布的方式,由于单纯分区还是在单台机器上的配置,所以主要讨论的是架构上分库(或是分库+分表)的实现和方案。
数据的分布一般最常见的有按范围分和按哈希分,当然能用的不止这两种,详细可以参考MyCat支持的分库分表方式。

自定义分布

存一个将ID和库的Mapping关系的单独的记录库,分布算法用另外的服务实现,分布算法服务可能会迭代,所以这种方式可能适合经常变动的业务,数据分布的关系自然就被记录在该mapping表里,实际中可能不太常见。
缺点是会引入新的单点,也就是引入了该mapping服务的高可用问题。

按范围分区间

按范围区分在实际应用中很常见,这个范围字段通常是某唯一 id 或时间字段,优点是自然增长,不需要考虑以后数据规模再次变大数据要重分布的问题;
缺点也是明显的,一般情况下密集访问的都是最近时间内的数据,密集访问其实还是集中在最近时间内产生的数据上,并发规模若再变高依旧存在密集访问的问题。

按某业务字段 Hash

通过业务字段值 Hash 处理后的值分布数据,这个数据分布方式也是很常见的实现方式,比如希望分 N 个库,可以按用户 ID 取模 N ,可以均匀地将用户相关的数据分布到不同的库上,若希望在数据库内再对表进行划分,可以再对该 ID 作 Hash 处理。Hash 算法的设计可能会业务不同而异因,我们可以学习一下美团技术团队分库分表方案上 Hash 算法的设计。

分库方案讨论

确定我们的业务的数据分布,技术选型就是接下来很重要的事情,我们了解发现现在业界现在分库分表的实现基本有在业务侧实现和通过中间件实现的方式。我可能还是偏向于用中间件的方式将分库分表的处理逻辑与业务剥离开,由运维或者 devops 去单独维护,好处是对开发完全透明,不使得已经比较复杂的业务代码变得更复杂。

分库中间件或开源库调研

现在业内使用的开源库或者中间件有多种,包括:Cobar、TDDL、Atlas、Sharding-jdbc、MyCat、kingshard。

业务端分库分表开源库

Sharding-jdbc:Sharding-jdbc 可能是 Java 系同学的福音,也是经常会看到的,已经发展到 ShardingSphere 了,有兴趣的同学自己去了解吧,我们这里不作研究了。

中间件

我们接下来对业界比较常见的,或者是我比较感兴趣的分库分表中间件作一下对比或者深入了解。

MyCat

mycat 的安装和启动方式我们这里就不做讨论了,mycat 官方文档都有描述。mycat 是用 Java 写的中间件,前身是或者参考了阿里的内部分布式中间件,在官网也能看到其功能介绍,使用于生产环境的公司等等,能看出来技术功底还是相当靠谱的,说是最常见最靠谱的中间件也不为过。与其它中间件一样,前面做一层负载均衡,比如用HAProxy等,也能作为一个常见的高可用方案。
另外社区还是相当活跃的,有大神在维护,用于生产环境比较让人安心的。具体介绍和操作都可以翻阅官方的文档,都解释得非常详细。

配置我们可以详细讨论一下,在结构上有这么几个概念:

  • Schema:逻辑库,也就是逻辑意义上的数据库,像是司机信息库等。
  • Table:逻辑表,表会绑定对应的一个或多个 DataNode (逻辑数据节点)。可以指定表的分片规则,不指定会使用默认规则。
  • DataNode:逻辑数据节点,该逻辑数据节点还会绑定 DataHost (物理物理数据节点)。
  • DataSource或DataHost:定义物理节点,同时保存物理节点信息诸如IP、最大连接数、heartbeat等。
  • 分片规则(rule):也就是我们设计的数据分布方式,数据会按该分片规则分布到对应的节点上。有多种默认的分片规则如哈希、范围,也可以根据业务情况自定义。

配置文件主要有:

  • schema.xml 配置逻辑表及数据节点
  • rule.xml 配置分片规则
  • server.xml 配置服务器权限

可以参考这个实例的 schema.xml 配置,rule.xml 和 server.xml 暂不作展示了:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

<!-- 数据库配置,与server.xml中的数据库对应 -->
    <schema name="db_person" checkSQLschema="false" sqlMaxLimit="100">
        <table name="person" dataNode="dn1"  />
        <table name="vehicle" dataNode="dn1"  />
        <table name="images" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2"  rule="mod-long" />
    </schema>

<!-- 分片配置 -->
    <dataNode name="dn1" dataHost="internal-01" database="db_person" />
    <dataNode name="dn2" dataHost="internal-02" database="db_person" />

<!-- 物理数据库配置 -->
    <dataHost name="internal-01" maxCon="1000" minCon="10" balance="0"  writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="172.190.0.2" url="172.190.0.2:3306" user="root" password="123456"> 
        </writeHost>
    </dataHost>

    <dataHost name="internal-02" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
        <heartbeat>select user();</heartbeat>
        <writeHost host="172.190.0.3" url="172.190.0.3:3306" user="root" password="123456"> 
        </writeHost>
    </dataHost>
</mycat:schema>

MyCat 的官方文档描述得非常详细,包括 MyCat 使用的网络 IO 并发模型都有阐述,如果对 MyCat 有兴趣,阅读一遍官方文档是非常有益于理解 MyCat 的。

kingshard

了解 kingshard 是因为 kingshard 是用 go 写的,在学习上成本会低很多,kingshard 是一位 go 大神维护的,听说将其使用在生产环境的公司也有不少,应该也是比较好的一款分库分表中间件,后面有时间我们可以来分析学习一下 kingshard 的具体实现。
kingshard 的结构或概念相对比较简单,支持多个表放在单个库上,后面再扩容在配置上也非常友好。

配置实例(/etc/ks.yaml):

user_list:
-
    user :  kingshard
    password : kingshard

# the web api server
web_addr: 0.0.0.0:9797
#HTTP Basic Auth
web_user: admin
web_password: admin

log_path: /Users/jerry/log
log_level: debug
log_sql: on

nodes :
-
    name : node1
    user :  root
    password : 123456
    max_conns_limit : 32
    master : 127.0.0.1:3307

    # slave represents a real mysql salve server,and the number after '@' is-
    # read load weight of this slave.
    #slave : 192.168.59.101:3307@2,192.168.59.101:3307@3
    down_after_noalive : 32
-
    name : node2
    user :  root
    password : 123456
    max_conns_limit : 32
    master : 127.0.0.1:3308
    down_after_noalive: 32
-
    name: node3
    user: root
    password: 123456
    master: 127.0.0.1:3309
    down_after_noalive: 32
-
    name: node4
    user: root
    password: 123456
    master: 127.0.0.1:3310
    down_after_noalive: 32

# schema defines sharding rules, the db is the sharding table database.
schema_list :
-
    user: kingshard
    nodes: [node1,node2,node3,node4]
    default: node1
    shard:
    -
        db : db_driver
        table: t_join_driver
        key: driver_join_id
        type: hash
        nodes: [node1, node2, node3, node4]
        locations: [4,4,4,4]

可以看到配置还是很简单的,定义节点( Node )信息,以及分库分表的 schema 信息,如表名、使用哪些节点、分库分表方式(如 hash )、数据分布等。接下来就是分别搭建每个数据库节点,即可启动。
不过我的客户端连接 kingshard 上一直连接不上,一直没找到问题所在,后面有时间我们可以来学习一下 MySQL 协议以及 kingshard 的实现。

Postgres-XL(pgsql)

以上都是使用 MySQL 作为后端数据库服务器的,但是数据库服务器界还有 pgsql 这么个泰斗级的存在,pgsql 功能强大,如果使用 pgsql 存储,那么也有已经使用于生产的分库分表方案,其中一个便是 Postgres-XL。
Postgres-XL是一个可横向扩展的开源数据库集群,基于Postgres-XC,而Postgres-XC又是基于PostgreSql。PostgreSQL许可证是一种自由开源许可证,类似于BSD或MIT许可证。
这里我们只展示一下 Postgres-XL 的架构,权作记录。


Postgres-XL架构图

后结

我们这里对于分库分表的学习和讨论还是偏于表层的,对于分库分表其实一直没有非常“干净”、从容又高效的解决方案,具体对每个不同中间件的使用还是要实际中磨合才能真正合适不同的业务。事实上现在不少大型互联网公司的存储引擎或者方案都是自研的,所以我们在使用开源中间件满足业务的同时,其实更有必要的是研究底层实现,比如什么样的网络IO并发模型是最合适本业务的、底层存储引擎是否真的是我们最想要的等等,因为很有可能分布式数据水平扩展问题并没有简单粗暴的“银弹”。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354