有分布式理论指导,遵循分布式系统的设计策略,具体而言也可以总结一些常见的分析系统设计实践。本文主要讨论几个通用性问题:

  • 全局ID生成;
  • 哈希取模分配;
  • 路由表;
  • 一致性哈希;
  • 数据拆分。

全局ID生成

目前TDDL(Taobao Distribute Data Layer)提供的id生成主要还是依托数据库来进行的,oracle可以直接使用sequence来完成,MySQL则需要DBA建立一个表专门用于生成id。

首先得思考一下,为什么存在全局ID这个问题?在分布式环境下,数据库是可以拆分(harding)的,一张表的自增机制(比如MySQL)只能保证该表唯一,在数据合并到历史库,迁移或者查询,如果出现id冲突无异于噩梦。

另外,由于数据库访问是高成本操作,也要避免每次INSERT都要到id生成器作DB层面的查询。我们来看看业界的一些方案。

UUID

UUID由以下几部分的组合:

  • 当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
  • 时钟序列
  • 全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。

优势:API简单、易用。

不足:占用空间大、字符串本身无法加工,可读性不强。

ID生成表模式

使用id生成表,比较经典的是Flicker的案例,Flicker在解决全局ID生成方案里就采用了MySQL自增长ID的机制。先创建单独的数据库,然后创建一个表:

CREATE TABLE 'Tickets64' ('id' bigint(20) unsigned NOT NULL auto_increment,'stub' char(1) NOT NULL default '',PRIMARY KEY ('id'),UNIQUE KEY stub ('stub')
) ENGINE=MyISAM

在我们的应用端需要做下面这两个操作,在一个事务会话里提交:

REPLACE INTO Tickets64(stub) VALUES('a');
SELECT LAST_INSERT_ID();

这样我们就能拿到不断增长且不重复的ID了,到上面为止,我们只是在单台数据库上生成ID,从高可用角度考虑,要解决单点故障问题,Flicker的方案是启用两台数据库服务器来生成ID,通过区分auto_increment的起始值和步长来生成奇偶数的ID。

这个方案优势简单易用,也有一定的高可用方案,不足是使用了mysql数据库的独特语法REPLACE INTO。

Snowflake

Twitter在把存储系统从MySQL迁移到Cassandra的过程中由于Cassandra没有顺序ID生成机制,于是自己开发了一套全局唯一ID生成服务:Snowflake。根据twitter的业务需求,snowflake系统生成64位的ID。由3部分组成:

  • 41位的时间序列(精确到毫秒,41位的长度可以使用69年);
  • 10位的机器标识(10位的长度最多支持部署1024个节点);
  • 12位的计数顺序号(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)。

优点:高性能,低延迟;独立的应用;按时间有序。

缺点:需要独立的开发和部署。

结合缓存方案

如下图所示,可以采取ID生成表模式成批获取id比如1000放到本地缓存(Local cache),这样在client使用的时候可进一步提升性能。

优点:高性能,低延迟。

缺点:ID不连贯。

哈希取模

哈希方式是最常见的数据分布方式,实现方式是通过可以描述记录的业务的id或key,通过Hash函数的计算求余。余数作为处理该数据的服务器索引编号处理,如下图所示。

这样的好处是只需要通过计算就可以映射出数据和处理节点的关系,不需要存储映射。难点就是如果id分布不均匀可能出现计算、存储倾斜的问题,在某个节点上分布过重。另外在调整数据存储,比如把2个库扩展成4个库,数据迁移是一个比较麻烦的事情。

以分布式缓存和拆分数据库的情况分别做一下说明。

分布式缓存,假设有3台server提供缓存服务,假设数据基本均衡,则每台机器缓存1/3的数据,如下图所示。

如果增加2台服务器则算法变成为Hash(key)/5,大部分数据都会出现不能命中的情况,如下图所示。

拆分数据库也存在扩容的问题,解决方法是先预设足够大的逻辑库,比如100个库,随着物理负载的增加,把对应的逻辑库迁移到新增的数据库上即可,对于应用透明,相当于在应用和物理数据库之间增加了一层映射关系。

一致性哈希

一致性哈希算法是在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法。主要解决单调性(Monotonicity)和分散性(Spread)的问题。单调性简单描述是哈希的结果应能够保证原有已分配的内容可以被映射到原有缓冲中去,避免在节点增减过程中导致不能命中。

按照常用的hash算法来将对应的key哈希到一个具有2的32次方个桶的空间中,即0~(2的32次方)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形,如下图所示。

在一致性哈希算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其他不会受到影响,如下图所示。

一致性哈希的优点在于任意动态添加、删除节点,每次添加、删除一个节点仅影响一致性哈希环上相邻的节点。为了尽可能均匀的分布节点和数据,一种常见的改进算法是引入虚节点的概念,系统会创建许多虚拟节点,个数远大于当前节点的个数,均匀分布到一致性哈希值域环上。这种增强型方案主要解决平衡性问题,所谓平衡性(Balance)是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。

路由表

什么情况下走到路由表模式,一般在于需要全局计算的节点。比如下图所示的场景,用户去抽奖,那么抽奖背后是有预算的。由于在高并发环境下比较单行记录热点,则对预算进行了拆分,并且拆分到不同逻辑数据库中去。那么如何知道,某些记录预算使用完没有呢,使用完的就不路由了。可以由子预算的服务更新后异步通知给预算。

采用路由表存在一个风险,就是数据是集中式管理的,存在单点风险。如果数据规模小,而数据库本身有备份机制或者failover能力,是可行的。

数据拆分

Cobar是一个著名的阿里巴巴开源的分布式数据库中间件。解决数据规模增加对于应用这层proxy的问题,Cobar支持的数据库结构(schema)的层次关系具有较强的灵活性,用户可以将表自由放置不同的datanode,也可将不同的datasource放置在同一MySQL实例上。如下图所示,在实际应用中,我们需要通过配置文件(schema.xml)来定义我们需要的数据库服务器和表的分布策略。

路由函数定义,应用在路由规则的算法定义中,路由函数可以自定义扩展。如下示例,我们可以看出分表的规则是,按照id字段把某表中的数据分配到db1和db2两个分区中,其中id小于1024的数据会被放到db2库的分区中。

<function name="func1" class="com.alibaba.cobar.route.function.PartitionByLong"><property name="partitionCount">2</property><property name="partitionLength">1024</property>
</function>

当当开源了sharding-jdbc,架构图如下图所示。

分布式:分布式系统设计实践。相关推荐

  1. 浅谈分布式 ID 的实践与应用

    导读:在业务系统中很多场景下需要生成不重复的 ID,比如订单编号.支付流水单号.优惠券编号等都需要使用到. 文|古德 网易云信资深 JAVA 开发工程师 本文将介绍分布式 ID 的产生原因,以及目前业 ...

  2. 高可用性的HDFS—Hadoop分布式文件系统深度实践

    <高可用性的HDFS-Hadoop分布式文件系统深度实践> 基本信息 作者: 文艾 王磊 出版社:清华大学出版社 ISBN:9787302282587 上架时间:2012-5-14 出版日 ...

  3. 基于Sql Server 2008的分布式数据库的实践(一)

    原文 基于Sql Server 2008的分布式数据库的实践(一) 配置Sql Server 2008(Win7) 1.打开SQL server2012,使用windows身份登录 2.登录后,右键选 ...

  4. 快上车!“正经”文章告诉你如何构建与使用分布式中间件平台实践

    首先,请相信我:这是一篇技术文章,正不正经,那就只有看完才能知道了! 前几天,一则"前沿数控因使用腾讯云而数据全部丢失"的新闻震惊了整个IT圈.当我看到这新闻的时候,突然的想法是这 ...

  5. 基于Sql Server 2008的分布式数据库的实践(五)

    基于Sql Server 2008的分布式数据库的实践(五) 原文 基于Sql Server 2008的分布式数据库的实践(五) 程序设计 ------------------------------ ...

  6. 企业级分布式事务设计实践解决方案

    摩天,用友旗下社会化的企业数智化学习认证社区,提供数智营销.智慧医疗.数智金融.智能制造.项目管理等精品课程,数智化人才上摩天!https://mot.yonyou.com/ 你将会学到: 能分析典型 ...

  7. 基于Sql Server 2008的分布式数据库的实践(三)

    原文 基于Sql Server 2008的分布式数据库的实践(三) 配置PHP 1.打开PHP配置文件,找到extension=php_mssql.dll,将前面的注释符号去掉 2.找到mssql.s ...

  8. WCF分布式安全开发实践(9):消息安全模式之Windows身份验证:Message_Windows_NetTcpBinding...

    今天继续WCF分布式安全开发实践(9):消息安全模式之Windows身份验证:Message_Windows_NetTcpBinding.本文介绍的内容主要是:主要是消息安全模式的Windows身份验 ...

  9. WCF分布式安全开发实践(6):传输安全模式之自定义X509Certificate证书验证

    今天继续WCF分布式安全开发实践(6):传输安全模式之自定义X509Certificate证书验证.本文介绍的内容主要是:主要是传输安全模式的UserNamePassword身份验证方式,基于WSHt ...

最新文章

  1. 跨界 | 土木工程也开始AI化了:用卷积神经网络实现结构损伤视觉识别
  2. 区块链开发:为什么你应该学习?
  3. javascript之回调函数小知识
  4. FCN网络的训练——以SIFT-Flow 数据集为例
  5. Charles+安卓模拟器 抓取https请求
  6. Java流程控制01 用户交互Scanner
  7. 华为在剑桥建芯片厂;小米公布出货量反驳调研机构; 中移动否认限制号 | 极客头条...
  8. Matlab实现批量修改文件名
  9. 二、Nginx 反向代理配置初学个人理解
  10. 有关《家》的经典歌曲_盘点《乐队的夏天》15首经典歌曲,太好听了!
  11. android studio改java,Android Studio如何修改快捷键
  12. 倍福触摸屏维修操作面板维修CP7032-1031-0010故障分析
  13. QQ音乐爬虫之放弃的路
  14. Docker之通过阿里云的镜像加速器快速拉取镜像到本地
  15. WPS表格 JSA-单格内,按文字颜色处理文字
  16. linux中jdk添加字体_在Linux上为Openjdk Java定义/安装字体的位置
  17. LeetCode(力扣)初级算法 字符串篇
  18. Qt QRegExp正则表达式
  19. suparc服务器没信号,SupARC对战平台新手上手教程
  20. ios本地文件读取方法详解

热门文章

  1. 深度学习基础----线性模型
  2. 对数组做交换(swap)会发生什么?
  3. 卸载kerberos
  4. 我在网易云音乐里看到的那些关于考研的故事
  5. 二十六篇,Linux库文件(动态库和静态库)的制作。
  6. 解决浏览器导出Excel文件名乱码问题
  7. 偏向锁,轻量级锁,重量级锁的核心原理
  8. 主从概念以及主从的相关知识
  9. 职场上35岁以上的人都去哪了?
  10. iPhone 5s 如何进入 DFU 模式,macOS 无法进入 DFU 模式