分库分表:
跨库的问题
分布式事务问题
查询数据结果集合并
全局唯一性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)字符存储、传输、查询慢、不可读
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
总结:
优点
不依赖数据、灵活方便、性能优于数据库的、没有单点故障(高可用)
缺点
需要占用网络资源、性能要比本地生成慢、需要增加插件