分布式id生成方案?
1、UUID
2、数据库自增序列
3、雪花算法
- 每个毫秒值包含的ID值很多,不够可以变动位数来增加,性能佳(依赖workId的实现)。
- 时间戳值在高位,中间是固定的机器码,自增的序列在低位,整个ID是趋势递增的。
- 能够根据业务场景数据库节点布置灵活挑战bit位划分,灵活度高。
- 强依赖于机器时钟,如果时钟回拨,会导致重复的ID生成,所以一般基于此的算法发现时钟回拨,都会抛异常处理,阻止ID生成,这可能导致服务不可用。
4、基于redis、zk、mongodb等中间件生成
Redis生成ID
- 定义:利用Redis的原子操作(如INCR和INCRBY命令)生成唯一的递增数值作为ID。
- 优点:
- 高性能,支持高并发环境。
- 简单且易于扩展。
- 缺点:
- 依赖于外部服务(Redis),需要管理和维护额外的基础设施。
- 网络依赖性:高度依赖网络。
Zookeeper生成ID
- 定义:通过Zookeeper的znode数据版本来生成序列号,可以生成32位或64位的数据版本号。
- 优点:
- 利用Zookeeper的分布式特性,保证ID的全局唯一性。
- 缺点:
- 依赖Zookeeper,系统复杂度增加。
- 在高并发环境下性能可能不理想。
- 网络依赖性:高度依赖网络。
5、数据库号段模式 Leaf-segment
- 定义:从数据库批量获取自增ID号段,然后在本地缓存并生成ID,直到号段用完再向数据库申请新的号段。美团的。
- 仍然存在单点故障风险(可通过集群模式解决)。
- 如果服务在用完ID段之前下线或重启,可能导致ID浪费。
- 可能存在多个节点同时请求ID区间的情况,依赖DB。
- 对网络的依赖相对较低,只在申请新的ID段时需要访问数据库。
6、自定义算法
- 根据具体业务需求,可以设计自定义的分布式ID生成算法。这些算法可能结合时间戳、随机数、机器标识等多种因素来生成唯一ID。
- 自定义算法的优点是可以根据业务需求灵活调整,但缺点是需要额外的开发和维护工作。
二、如何实现分库分表
- 分库:每个库结构一样,数据不一样,没有交集。库多了可以缓解io和cpu压力
- 分表:每个表结构一样,数据不一样,没有交集。表数量减少可以提高sql执行效率、减轻cpu压力
- 分库:每个库结构、数据都不一样,所有库的并集为全量数据
- 分表:每个表结构、数据不一样,至少有一列交集,用于关联数据,所有表的并集为全量数据
Master slave
查多于写的场景,写在主库,查询在从库,复制Binlog日志。
代理层实现读写分离:
atlas:Db1、db2、proxy代理 配置文件 proxy配置主从关系 设置端口1234 通过代理层进行查询从库
解决主库读的压力
强制路由 主从同步走网络,极端情况下出现延迟,从库:I/O线程 进行binlog + DB线程
导致数据不能及时同步,从库查不到主库已有的数据,同步不及时,解决?强制路由
在查询语句前加:
/*master*/ select * from t1 where a =1;
垂直分库:
垂直分表:
User表
Tid | Name | Password | Sex | | Tel | | Wx | Hobby |
1 | 张三 | 123 | 1 | 2 | 3 | 4 | 5 | 6 |
2 | 李四 | 456 | 1 | 3 | 5 | 6 | 7 | 8 |
User_base
Tid | Name | Password |
1 | 张三 | 123 |
2 | 李四 | 456 |
User_info
Tid | Sex | | Tel | | Wx | Hobby |
1 | 1 | 2 | 3 | 4 | 5 | 6 |
2 | 1 | 3 | 5 | 6 | 7 | 8 |
垂直拆分:每个库表的结构不一样、每个库表的数据都至少有一列、每个库表的并集是全部数据。
优点:拆分业务清晰(专库专用)、数据维护简单,按业务不同放到不同机器上
缺点:如果单表的数据量大,读写压力大;
受某种业务场景决定、限制,一个业务影响其他数据库的瓶颈,性能问题,如双11,商品、订单库压力大,用户库压力小;
部分业务无法关联join,只能通过程序调用,开发复杂。
数据分布不均匀,有的库数据量大。
水平分库
水平分表
User表
Tid | Name | Password | Sex | | Tel | | Wx | Hobby |
1 | 张三 | 123 | 1 | 2 | 3 | 4 | 5 | 6 |
2 | 李四 | 456 | 1 | 3 | 5 | 6 | 7 | 8 |
User表1
Tid | Name | Password | Sex | | Tel | | Wx | Hobby |
1 | 张三 | 123 | 1 | 2 | 3 | 4 | 5 | 6 |
User表2
Tid | Name | Password | Sex | | Tel | | Wx | Hobby |
2 | 李四 | 456 | 1 | 3 | 5 | 6 | 7 | 8 |
水平拆分:每个库表的结构一样、每个库表的数据不一样、每个库表的并集是全量数据、数据均分。
优点:单库的数据量小,有助于性能提升;
切分的表的结构相同,程序改造较少;
提高系统稳定性和负载能力
缺点: 数据扩容困难
拆分规则很难抽象出来
分片事务的一致性 部分业务无法关联join 只能通过程序调用
需要分布式事务
跨库查询问题?怎样确认一条数据在哪个库
分布式全局唯一ID?每个库中的id一样咋办
分库分表的中间件:
Proxy代理层:mycat、atlas、mysql-proxy
jdbc增强 应用层:shardingshpere、TDDL shardingshpere阿帕奇的