JAVA互联网架构分库分表分布式下如何实现ID全局唯一性

 分库分表:


    跨库的问题

    分布式事务问题

    查询数据结果集合并

    全局唯一性ID保证

    要求:

    1、全局唯一性:不能出现重复的id号(基本的要求)。

    2、信息安全:防止恶意用户规矩id的规则来获取数据。混淆效果

    3、数据递增:保证我下一个ID一定大于上一个ID.

    当前201709122030 下一个:201709122031 下一个:201709122032

    互斥关系:信息安全、数据递增规律

    CREATE TABLE `tl_id` (

    `id` varchar(255) NOT NULL,

    PRIMARY KEY (`id`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    业界分案:

    UUID:

    通用唯一识别码 16个字节128位的长数字、

    组成部分:当前日期和时间序列+全局的唯一性网卡mac地址

    执行任务数:10000

    ------------------------

    所有线程共耗时:38.305 s

    并发执行完耗时:449.0 ms

    单任务平均耗时:3.8305 ms

    单线程最小耗时:0.0 ms

    单线程最大耗时:193.0 ms

    总结:

    优点

    代码实现简单、不占用宽带、数据迁移不受影响

    缺点

    无序、无法保证趋势递增(要求3)字符存储、传输、查询慢、不可读

潍坊Java培训

    Snowflake雪花算法

    国外的twitter分布式下iD生成算法

    1bit+41bit+10bit+10+bit=62bit

    高位随机+毫秒数+机器码(数据中心+机器id)+10的流水号

    国内:

    保证数据的唯一性就行了 IDC机房。总结:

    优点

    代码实现简单、不占用宽带、数据迁移不受影响、低位趋势递增

    缺点
 

    强以来时钟(多台服务器时间一定要一样)、无序无法保证趋势递增(要求3)

 

    水平切分方式

    范围法

    哈希法

    水平切分后碰到的问题

    通过uid属性查询能直接定位到库,通过非uid属性查询不能定位到库。

    非uid属性查询的典型业务

    用户侧,前台访问,单条记录的查询,访问量较大,服务需要高可用,并且对一致性的要求较高。

    运营侧,后台访问,根据产品、运营需求,访问模式各异,基本上是批量分页的查询,由于是内部系统,访问量很低,对可用性的要求不高,对一致性的要求也没这么严格。

    用户侧与运营侧架构设计思路

    针对用户侧,应该采用“建立非uid属性到uid的映射关系”的架构方案。

    针对运营侧,应该采用“前台与后台分离”的架构方案。

    用户前台侧,“建立非uid属性到uid的映射关系”最佳实践

    索引表法:数据库中记录login_name->uid的映射关系。

    缓存映射法:缓存中记录login_name->uid的映射关系。

    login_name生成uid.

    login_name基因融入uid.

    运营后台侧,“前台与后台分离”最佳实践

    前台、后台系统web/service/db分离解耦,避免后台低效查询引发前台查询抖动。

    可以采用数据冗余的设计方式。

    可以采用“外置索引”(例如ES搜索系统)或者“大数据处理”(例如HIVE)来满足后台变态的查询需求。

    “1对多”类业务,在架构上,采用元数据与索引数据分离的架构设计方法

    帖子服务,元数据满足uid和tid的查询需求。

    搜索服务,索引数据满足复杂搜索寻求。

    对于元数据的存储,在数据量较大的情况下,有三种常见的切分方法:

    tid切分法,按照tid分库,同一个用户发布的帖子落在不同的库上,通过 - uid来查询要遍历所有库。

    uid切分法,按照uid分库,同一个用户发布的帖子落在同一个库上,需要通过索引表或者缓存来记录tid与uid的映射关系,通过tid来查询时,先查到uid,再通过uid定位库。

    基因法,按照uid分库,在生成tid里加入uid上的分库基因,保证通过uid和tid都能直接定位到库。

    在数据库架构设计过程中,除了水平切分,至少还会遇到这样一些问题:

    可用性:不管是主库实例,还是从库实例,如果数据库实例挂了,如何不影响数据的读和写。

    读性能:互联网业务大多是读多写少的业务,如果提升数据库的读性能是架构设计中必须考虑的问题。

    一致性:数据一旦冗余,就可能出现一致性问题,如何解决主库与从库之间的不一致,如何解决数据库与缓存之间的不一致,也是需要重点设计的。

    扩展性:如何在不停服务的情况下扩充数据表的属性,实施数据迁移,实施存储引擎的切换,架构设计上都是十分有讲究的。

    分布式SQL语句:单库情况下,所有SQL语句的执行都没问题问题,一旦实施了水平切分,如何实现SQL的集函数,分页,非patition key上的查询都成了大问题。

    Mysql:

    奇数跟我们偶数 递增步长2

    适合小型互联网公司、比如可以知道我们一定生成的ID数量 五万的订单量

    一年1千8百万

    Mysql一张表500万

    如果公司每天订单量5万的数据 我们用mysql设置步长位100的话可以用27年

    只能为100库 公司来到风投了 每天的订单量50万100万的时候

    总结:

    优点

    代码实现方便、性能不错、数字排序、可读性很强

    缺点

    受限数据库、扩展麻烦、插入数据库才能拿到ID、单点故障的问题

    主从同步的时候:电商下单->支付 insert master db select 数据 因为数据同步延迟导致查不到这个数据。加cache(不是最好的解决方式)数据要求比较严谨的话查master主库。

    CREATE TABLE `tl_num` (

    `id` bigint(11) NOT NULL AUTO_INCREMENT,

    KEY (`id`) USING BTREE

    ) ENGINE=InnoDB auto_increment=1 DEFAULT CHARSET=utf8;

    Redis:

    执行任务数:10000

    ------------------------

    所有线程共耗时:136.587 s

    并发执行完耗时:1.515 s

    单任务平均耗时:13.6587 ms

    单线程最小耗时:1.0 ms

    单线程最大耗时:254.0 ms

    总结:

    优点

    不依赖数据、灵活方便、性能优于数据库的、没有单点故障(高可用)

    缺点
 

    需要占用网络资源、性能要比本地生成慢、需要增加插件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值