学院网站模板,移动网站怎么做,网站免费正能量直接进入app,建设一个网站需要什么人员文章目录 全局唯一id介绍 全局唯一id特点:常见全局唯一id生成策略 1、数据库自增长序列或字段生成id 2、UUID 3、Redis生成ID 4、zookeeper生成ID 5、Twitter的snowflake算法全局唯一id介绍 系统唯一id是我们在设计阶段常常遇到的问题。在复杂的分布式系统中#… 文章目录 全局唯一id介绍 全局唯一id特点:常见全局唯一id生成策略 1、数据库自增长序列或字段生成id 2、UUID 3、Redis生成ID 4、zookeeper生成ID 5、Twitter的snowflake算法全局唯一id介绍 系统唯一id是我们在设计阶段常常遇到的问题。在复杂的分布式系统中几乎都需要对大量的数据和消息进行唯一标识。在设计初期我们需要考虑日后数据量的级别如果可能会对数据进行分库分表那么就需要有一个全局唯一id来标识一条数据或记录。生成唯一id的策略有多种但是每种策略都有它的适用场景、优点以及局限性。 全局唯一id特点: 全局唯一性不能出现重复的ID号既然是唯一标识这是最基本的要求趋势递增在MySQL InnoDB引擎中使用的是聚集索引由于多数RDBMS使用B-tree的数据结构来存储索引数据在主键的选择上面我们应该尽量使用有序的主键保证写入性能单调递增保证下一个ID一定大于上一个ID例如事务版本号、IM增量消息、排序等特殊需求信息安全如果ID是连续的恶意用户的扒取工作就非常容易做了直接按照顺序下载指定URL即可如果是订单号就更危险了竞对可以直接知道我们一天的单量。所以在一些应用场景下会需要ID无规则、不规则高可用性同时除了对ID号码自身的要求业务还对ID号生成系统的可用性要求极高想象一下如果ID生成系统瘫痪这就会带来一场灾难。所以不能有单点故障分片支持可以控制ShardingId。比如某一个用户的文章要放在同一个分片内这样查询效率高修改也容易长度适中。常见全局唯一id生成策略 1、数据库自增长序列或字段生成id 最常见的一种生成id方式。利用数据库本身来进行设置在全数据库内保持唯一。 【优点】 非常简单。利用现有数据库系统的功能实现成本小代码简单性能可以接受。ID号单调递增。可以实现一些对ID有特殊要求的业务比如对分页或者排序结果这类需求有帮助。【缺点】 1. 强依赖DB。不同数据库语法和实现不同数据库迁移的时候、多数据库版本支持的时候、或分表分库的时候需要处理会比较麻烦。当DB异常时整个系统不可用属于致命问题。 2. 单点故障。在单个数据库或读写分离或一主多从的情况下只有一个主库可以生成。有单点故障的风险。 3. 数据一致性问题。配置主从复制可以尽可能的增加可用性但是数据一致性在特殊情况下难以保证。主从切换时的不一致可能会导致重复发号。 4. 难于扩展。在性能达不到要求的情况下比较难于扩展。ID发号性能瓶颈限制在单台MySQL的读写性能。 【部分优化方案】 针对主库单点 如果有多个Master库则每个Master库设置的起始数字不一样步长一样可以是Master的个数。比如Master1 生成的是 14710Master2生成的是2,5,8,11 Master3生成的是 3,6,9,12。这样就可以有效生成集群中的唯一ID也可以大大降低ID生成数据库操作的负载。 2、UUID 常见的生成id方式利用程序生成。 UUID (Universally Unique Identifier) 的目的是让分布式系统中的所有元素都能有唯一的辨识资讯而不需要透过中央控制端来做辨识资讯的指定。如此一来每个人都可以建立不与其它人冲突的 UUID。在这样的情况下就不需考虑数据库建立时的名称重复问题。 UUID的标准形式包含32个16进制数字以连字号分为五段形式为8-4-4-4-12的36个字符示例550e8400-e29b-41d4-a716-446655440000到目前为止业界一共有5种方式生成UUID详情见IETF发布的UUID规范 A Universally Unique IDentifier (UUID) URN Namespace。 在Java中我们可以直接使用下面的API生成UUID: UUID uuid UUID.randomUUID(); String s UUID.randomUUID().toString();【优点】 非常简单本地生成代码方便API调用方便。性能非高。生成的id性能非常好没有网络消耗基本不会有性能问题。全球唯一。在数据库迁移、系统数据合并、或者数据库变更的情况下可以 从容应对。【缺点】 存储成本高。UUID太长16字节128位通常以36长度的字符串表示很多场景不适用。如果是海量数据库就需要考虑存储量的问题。信息不安全。基于MAC地址生成UUID的算法可能会造成MAC地址泄露这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。不适用作为主键ID作为主键时在特定的环境会存在一些问题比如做DB主键的场景下UUID就非常不适用。UUID往往是使用字符串存储查询的效率比较低。UUID是无序的。不是单调递增的而现阶段主流的数据库主键索引都是选用的B树索引对于无序长度过长的主键插入效率比较低。传输数据量大。不可读。【部分优化方案】 为了解决UUID不可读 可以使用UUID to Int64的方法 。 为了解决UUID无序的问题 NHibernate在其主键生成方式中提供了Comb算法combined guid/timestamp。保留GUID的10个字节用另6个字节表示GUID生成的时间DateTime。 3、Redis生成ID 当使用数据库来生成ID性能不够要求的时候我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。 可以使用Redis集群来获取更高的吞吐量。假如一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5然后步长都是5。各个Redis生成的ID为 A1,6,11,16,21 B2,7,12,17,22 C3,8,13,18,23 D4,9,14,19,24 E5,10,15,20,25 这个负载到哪台机器上需要提前设定好未来很难做修改。但是3-5台服务器基本能够满足都可以获得不同的ID。步长和初始值一定需要事先设定好。使用Redis集群也可以防止单点故障的问题。 比较适合使用Redis来生成日切流水号。比如订单号日期当日自增长号。可以每天在Redis中生成一个Key使用INCR进行累加。 【优点】 不依赖于数据库灵活方便且性能优于数据库。。数字ID天然排序对分页或者需要排序的结果很有帮助。【缺点】 如果系统中没有Redis还需要引入新的组件增加系统复杂度。。 需要编码和配置的工作量比较大。 Redis单点故障影响序列服务的可用性。 4、zookeeper生成ID zookeeper主要通过其znode数据版本来生成序列号可以生成32位和64位的数据版本号客户端可以使用这个版本号来作为唯一的序列号。 很少会使用zookeeper来生成唯一ID。主要是由于需要依赖zookeeper并且是多步调用API如果在竞争较大的情况下需要考虑使用分布式锁。因此性能在高并发的分布式环境下也不甚理想。 5、Twitter的snowflake算法 snowflake(雪花算法)是Twitter开源的分布式ID生成算法结果是一个long型的ID。这种方案把64-bit分别划分成多段分开来标示机器、时间等。如图 其核心思想是使用41bit作为毫秒数10bit作为机器的ID5个bit是数据中心5个bit的机器ID12bit作为毫秒内的流水号意味着每个节点在每毫秒可以产生 4096 个 ID最后还有一个符号位永远是0。具体实现的代码可以参看github。 snowflake算法可以根据自身项目的需要进行一定的修改。比如估算未来的数据中心个数每个数据中心的机器数以及统一毫秒可以能的并发数来调整在算法中所需要的bit数。 【优点】 稳定性高不依赖于数据库等第三方系统以服务的方式部署稳定性更高生成ID的性能也是非常高的。灵活方便可以根据自身业务特性分配bit位。单机上ID单调自增毫秒数在高位自增序列在低位整个ID都是趋势递增的。【缺点】 强依赖机器时钟如果机器上时钟回拨会导致发号重复或者服务会处于不可用状态。 ID可能不是全局递增。在单机上是递增的但是由于涉及到分布式环境每台机器上的时钟不可能完全同步也许有时候也会出现不是全局递增的情况。 --------------------- 作者梦 * 蝶 来源CSDN 原文https://blog.csdn.net/LZ15932161597/article/details/113397226 版权声明本文为作者原创文章转载请附上博文链接 内容解析ByCSDN,CNBLOG博客文章一键转载插件