当前位置: 首页 > news >正文

迅 网站 模板自己电脑做服务器建网站

迅 网站 模板,自己电脑做服务器建网站,网剧推广一次5元,网络公司哪个平台好目录 前言 一#xff1a;分布式ID的使用场景 二#xff1a;分布式ID设计的技术指标 三#xff1a;常见的分布式ID生成策略 3.1 UUID 3.2 数据库生成 3.3 数据库的多主模式 3.4 号段模式 3.5 雪花算法 前言 分布式ID的生成是分布式系统中非常核心的基础性模块#…目录 前言 一分布式ID的使用场景 二分布式ID设计的技术指标 三常见的分布式ID生成策略 3.1 UUID 3.2 数据库生成 3.3 数据库的多主模式 3.4 号段模式 3.5 雪花算法 前言 分布式ID的生成是分布式系统中非常核心的基础性模块其常用于在分布式环境下作为数据或消息的唯一性的标识。 在互联网发展早期由于用户量较少,业务需求也比较简单。对于软件应用我们只需要一台高配置的服务器把业务所有模块全单机部署这样的软件架构模式称为单体架构模式。 在这种架构模式下为了为数据生成唯一性的标识ID一般有以下两种方案 1) 在服务器层面主动的填充好ID再将数据记录保存数据库。 2) 强依赖于数据库表的自增ID服务器生成的数据记录不需要先填充ID交由数据库来自动填充自增ID。 随着用户量的增加客户端请求的并发量越来越大在这个过程中单体架构因为其单机硬件资源的瓶颈造成以下问题 1随着并发量的逐渐增大客户端的请求RT时间越来越大请求超时失败概率越来越大。 2单机架构会存在单点故障问题。 为了解决上述的问题在并发量较高的场景中我们会进行分库分表将数据库进行集群化部署。 在复杂的分布式系统中我们需要对大量的数据和消息进行唯一性标识在数据库进行分库分表后数据库表的自增ID显然不满足需求。此时急需一个分布式ID的生成方案。 一分布式ID的使用场景 分布式ID的使用前提就是在复杂的分布式系统中我们需要对大量的数据和消息进行唯一性标识。 1用户会员等成员身份的唯一标识。 2订单支付金融等业务场景。 3)  优惠卷的兑换码 4)  加密文件的密码 总之需要在复杂分布式系统中需要对大量数据和消息进行唯一性标识那么就应当使用分布式ID。 二分布式ID设计的技术指标 首先实现分布式全局唯一ID的解决方案有很多比如说Mysql的主键维护表数据库的号段模式Zookeeper的有序节点MongoDB的ObjectIDRedis的自增IDUUID雪花算法........ 以上方案自然满足了在分布式环境下生成ID的唯一性的标准但是在实际生产环境中考虑一个分布式ID解决方案是否达标还应该考虑其它的技术指标。 分布式ID设计的技术指标可以用来评估一个分布式ID解决方案是否满足实际的生产环境也可以用来评估分布式ID解决方案的优劣。 1全局唯一性分布式ID的全局唯一性是最基础的指标是分布式ID解决方案必须保证的指标。 2有序性分布式ID常用来作为数据库的主键存在例如Mysql数据库有序的ID能够显著提升B树的维护效率避免因为ID的无序性导致数据新增时造成频繁的页分裂避免大量数据迁移造成的大量磁盘随机IO的代价。 3安全性: 分布式ID不一定是无规则杂乱无章的通常还会代表一些实际的意义。(比如 生成当前分布式ID的时间 用于标识当前机器的唯一标识 等)。正因为有了这些实际的意义可以方便于进行统计数据分析等工作。但分布式ID不因该携带敏感信息否则可能被恶意爬取数据造成数据泄露风险。 4可用性:分布式ID是分布式系统中非常核心的基础模块众多业务都依赖于分布式ID来对大量数据和消息进行唯一性标识。因此实际生产环境对ID生成系统的可用性要求极高一旦ID生成系统出现不可用可能会导致整个业务系统瘫痪。 5高性能分布式唯一ID生成系统需要满足整个公司业务的需求可能涉及亿级别的调用对性能要求较高。 三常见的分布式ID生成策略 3.1 UUID UUID(Universally Unique Identifier)通用唯一识别码。UUID到目前为止总共迭代了五个版本每个版本生成UUID的算法都不一样适用于不同的场景。 UUID 是由一组32位数的16进制数字所构成以连字号分隔的五组来显示形式为 8-4-4-4-12总共有 36个字符即三十二个英数字母和四个连字号)占36个字节的存储空间。例如 aefbbd3a-9cc5-4655-8363-a2a43e6e6c80 xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx UUID是基于当前时间、计数器counter和硬件标识通常为无线网卡的MAC地址等数据计算生成的。 此版本的UUID由以下几个部分组成 1当前日期和时间可以保证在不同日期和时间生成的ID一定不同。 2自增的计数器可以保证在并发环境下的性能相同时间内并发生成的多个UUID的计数器是自增的。 3 当前机器的唯一标识码全局唯一的IEEE机器识别号如果有网卡从网卡MAC地址获得没有网卡以其他方式获得。可以保证不同机器生成的UUID一定不同。     当然UUID也有根据 随机数基于名字空间/名字的散列值 (MD5/SHA1) 生成等生成的版本。 如果仅仅只是要求生成的ID唯一性那么UUID也是可以使用的。但根据上面讲的分布式ID设计的技术指标UUID其实是不能作为分布式ID的原因如下 首先分布式id一般都会作为主键但是安装mysql官方推荐主键要尽量越短越好UUID每一个都很长所以不是很推荐 既然分布式id是主键然后主键是包含索引的然后mysql的索引是通过b树来实现的每一次新的UUID数据的插入为了查询的优化都会对索引底层的b树进行修改因为UUID数据是无序的所以每一次UUID数据的插入都会对主键生成的b树进行很大的修改这一点很不好 信息不安全基于MAC地址生成UUID的算法可能会造成MAC地址泄露这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。 那么哪些情况下使用UUID也是可以的呢 一般满足下面三个条件才建议使用UUID 1. 不用ID做数据库的主键(Mysql的主键) 2. 只要求生成ID的唯一性 3. 对ID的顺序性不做要求 4. 并发量不是很高的场景 例如: 1. 做优惠卷的兑换码 2. 身份唯一标识(会员) 3. 需要解密才能打开的文件的解密密码 但一般场景中对于分布式唯一ID的使用场景都不会去考虑UUID 3.2 数据库生成 针对于数据库表结构的主键在单机情况下我们可以在创建表的时候设置auto_increment参数依赖于数据库本身表结构的自增来保证ID的唯一性。 但在复杂的分布式场景中面对越来越高的并发请求一般都会进行分库分表的配置而数据库的auto_increment只能保证单个数据库的单个表ID的唯一性无法实现全局唯一ID。 解决方案就是创建一个主键维护表在将消息和数据进行存储之前先向统一的主键维护表获取一个ID封装好数据记录后再向分库分表的数据库进行存储不依赖于单个数据库的自增来保证ID的唯一性。 案例讲解 1. 主键维护表的创建 CREATE TABLE test_order_id (id bigint NOT NULL AUTO_INCREMENT,title char(1) NOT NULL,PRIMARY KEY (id),UNIQUE KEY title (title) ) ENGINE InnoDB AUTO_INCREMENT1 DEFAULT CHARSET utf8; 2. 向主键维护表中获取ID BEGIN;REPLACE INTO test_order_id (title) values (p) ; SELECT LAST_INSERT_ID();COMMIT; 这种方案的优缺点如下: 优点: 1) 代码简单实现轻量化可以在原有的数据库系统实现成本较低。 2可以生成全局唯一且递增的ID满足需要ID递增的特殊业务场景。 缺点 1存在单点故障的问题一旦主键维护表所在的数据库服务器发生单点故障可能会导致整个业务系统瘫痪。 2存在较为明显的性能瓶颈仅能支持并发量较小的场景。基于磁盘做数据存储的数据库其性能受制于磁盘IO。当前方案性能受制于单台Mysql数据库的IO能力。 虽然第一个缺点我们可以配置数据库主从高可用模式来解决但是数据库主从架构模式下怎么去保证数据的一致性是一个很难办的问题。可能会存在主从切换时因为数据不一致从而导致Mysql数据维护表发出的ID出现重复(而这是分布式ID生成器绝对不能容忍的问题)。 哪怕我们通过数据主从高可用模式解决了单点故障问题但其性能仍然受制于单台Mysql数据库的IO能力满足不了并发量稍高的生产环境。 3.3 数据库的多主模式 单节点数据库方式存在明显的性能问题我们可以采用数据库的多主集群模式既可以解决单机数据库存在的单点故障问题又可以在一定程度上解决单点数据库存在的性能瓶颈问题。 所谓的多主集群模式指的是用多台数据库服务器作为主键维护表都可以单独生产自增ID且各自生产的自增ID不会重复。 这里就以数据库的双主集群模式为例子讲讲如何实现数据库的多主集群模式。 实现数据库的多主集群模式主要关注以下两个参数 1auto-increment-increment 自增的步长 2auto-increment-offset 自增的起始值 核心思路就是设置多台数据库以一定的步长和不同的起始自增值。 那么实现双主集群模式只需要让其中一台生产偶数趋势递增的ID让另外一台生产奇数趋势递增的ID。也就是进行如下配置: TicketServer1: auto-increment-increment 2 auto-increment-offset 1 TicketServer2: auto-increment-increment 2 auto-increment-offset 2 这种架构模式貌似满足了性能的需求且实现了高可用但任然存在以下的缺点: 1) 在并发量比较高的时候可能需要进行扩容但此架构设计进行水平拓展的代价十分高昂。 2在高并发的情况下显得难以为继基于磁盘存储的数据库受制于磁盘IO性能有其天生的性能缺陷。虽然可以通过堆机器在一定程度上解决性能瓶颈但代价十分高昂。 3每次获取分布式唯一ID的时候都需要进行访问数据库对Mysql压力过大。 3.4 号段模式 单纯的使用数据库主键维护表生产分布式ID会有性能瓶颈问题哪怕使用数据库多主集群模式来提升性能仍然会出现在高并发情况下每次获取分布式唯一ID的时候都需要进行数据库访问对Mysql的压力过大。 数据库的号段模式可以理解为从数据库中批量的获取自增ID每次从数据库中获取一个号段范围例如[1,1000]代表1000个ID,具体的分布式ID发号器将号段缓存到内存中然后通过自增的方式来发放分布式ID。 实现案例讲解: 1. 数据库中创建业务号段维护表 CREATE TABLE id_generator (id int(10) NOT NULL AUTO_INCREMENT,max_id bigint(20) NOT NULL COMMENT 当前最大id,step int(20) NOT NULL COMMENT 号段的布长,biz_type int(20) NOT NULL COMMENT 业务类型,version int(20) NOT NULL COMMENT 版本号,PRIMARY KEY (id) ) 下面解释业务号段维护表中各个字段的含义 id自增主键标识唯一记录 max_id: 当前业务可用的最大ID的编号,每次领取号段的时候都会更新此字段 step: 当前业务单次领取号段的步长 biz_type: 业务的类型编号 version乐观锁每次更新 max_id 时都会更新版本号用来保证并发环境下的正确性 2. 分布式ID发号器从业务号段表中获取新的号段 BEGIN;select max_id,version,step from id_generator where biz_typecurrent_group ;# current_group 为传入的参数update id_generator set max_idmax_idstep # step 为传入的参数 and versionversion1 where versionexcpet_version # excpet_version 为期望的版本号COMMIT; 3.分布式ID发号器通过CAS领取号段 分布式ID发号器在向数据库业务号段维护表请求新的号段的时候可能会因为以下两个原因失败: 1. 网络发生故障或者拥塞导致请求出现任意量的丢包或者延迟。 2. 当分布式ID发号器进行水平拓展时可能会有多个分布式ID发号器并发向数据库业务号段表去申请同一个业务下的号段可能会出现并发错误因此需要CAS(compare and swap)比较版本号是否与第一个查询语句查出的版本号一致如果一致再执行第二个update语句。 因此再执行完上述SQL语句后得判断update语句是否修改了记录如果没有修改说明CAS失败需要重试直到成功修改记录说明向数据库业务号段表领取号段成功。 这种方式的优缺点如下: 优点 1. 高性能由于批量的从数据库获取自增ID其性能摆脱了基于磁盘存储的数据库的限制一般分布式ID发号器会通过RPC对外提供服务那么其性能瓶颈主要在网络带宽。但其性能一般都能到达几十万QPS在实际高并发业务场景中完全足够。 2. ID号码是趋势递增的8byte的64位数字满足上述数据库存储的主键要求。 3. 容灾性高虽然强依赖于数据库但是分布式ID发号器可以内存级别缓存一定的号段即使数据库宕机也能提供一段时间的服务。(建议号段的步长step设置为QPS的600倍数据库宕机后也可以用10min)。 缺点 1. 强依赖于数据库要求数据库有很高的可用性。数据库主从架构模式下怎么去保证数据的一致性是一个很难办的问题。可能会存在主从切换时因为数据不一致从而导致Mysql数据维护表发出的ID出现重复。需要主从同步复制来保证。 2. ID号码不够随机能够泄露发号数量的信息不太安全。不适合做订单的ID。 3. 当号段使用完后需要向数据库请求新的号段此时数据库的性能会卡在数据库的IO性能上。 3.5 雪花算法 Snowflake雪花算法是有Twitter开源的分布式ID生成算法以划分命名空间的方式将64bit位分割成了多个部分每个部分都有具体的不同含义在Java中64Bit位的整数是Long类型所以在Java中Snowflake算法生成的ID就是long来存储的。具体如下: 雪花算法是基于时间戳和自增序列号的方式来保证单机生成的ID的唯一性通过对不同机器设置不同的工作机器id来确保在复杂的分布式环境中生成的ID是满足全局唯一性的。 第一部分符号位占用1个比特位用来标识是正负数但一般情况下均是正数 第二部分41bit位的时间戳用来标识生成此ID的时间到起始时间的差值(单位是ms)。那么雪花算法的使用年限:(2^41)/(1000*60*60*24*365)69年 第三部分占用10bit位表示雪花算法支持的机器数即最多支持 2^101024台机器但通常不会部署这么多台机器。注意一个业务组下多台分布式ID发号器的工作机器id必须不同。 第四部分占用12bit位表示的是毫秒内的自增序号由于 2^124096个 所以雪花算法最多1ms内生成4096个ID。 下面给出用Java语言实现的Twitter雪花算法 public interface IIdGenerator {/*** ID生成器策略接口* 获取生成的下一个ID* return*/public long nextId();} /*** ClassName SnowFlake* Description TODO: 雪花算法ID生成策略* 雪花算法是有Twitter开源的分布式ID生成算法* 以划分命名空间的方式将64bit位分割成了多个部分* 每个部分都有具体的不同含义** 当前代码是雪花算法用Java语言实现的版本*** 想要确保生成的分布式ID是全局唯一的* 当前类应该在进程中是单例的* 且生成ID是串行生成的* Author 快乐的星球* Date 2023/9/23 10:37* Version 1.0**/ public class Snowflake implements IIdGenerator {/*** 硬件机器的编号*/private long workId;/*** 工作机器的编号占用5个比特位* 0-31*/private static final long WORK_ID_BITS5;/*** 数据中心编码*/private long dataCenter;/*** 数据中心编码占用5个比特位* 0-31*/private static final long DATA_CENTER_BITS5;/*** 雪花算法的起始基准时间* 2023年10月1日 0时0分0秒*/private static final long START_TIMESTAMP1696089600000L;/*** 占用41比特位的时间戳* 记录的时 分布式ID发号的时间 到 起始时间 相距的毫秒数*/private static final long TIMESTAMP_BITS41;/*** 符号位占的比特位 1*/private static final long FLAG_BITS1;/*** 12位的自增序列号*/private static final long SEQUENCE_BITS12;/*** 自增序列号的掩码* 默认 4095*/private static final long SEQUENCE_MASK(-1L^(-1L SEQUENCE_BITS));/*** 颁发上*/private long lastTimestamp-1L;/*** 工作编码左移的位数*/private static final long WORK_ID_SHIFTSEQUENCE_BITS;/*** 数据中心左移的位数*/private static final long DATA_CENTER_SHIFTSEQUENCE_BITSWORK_ID_BITS;/*** 时间戳左移的位数*/private static final long TIMESTAMP_SHIFTSEQUENCE_BITSWORK_ID_BITSDATA_CENTER_BITS;/*** 当前自增的序列号*/private long sequence;public Snowflake(long dataCenter, long workId){Assert.checkBetween(dataCenter,0,Math.pow(2,5)-1);Assert.checkBetween(workId,0,Math.pow(2,5)-1);this.dataCenterdataCenter;this.workIdworkId;}Overridepublic synchronized long nextId() {//1: 获取当前时间戳long currentTimestamp currentTimestamp();//2: 校验是否出现了时针回拨if(currentTimestamplastTimestamp){throw new RuntimeException(发生了时针回拨!颁发当前ID的时间比颁发 上一个ID的时间要小!当前时间:{currentTimestamp}, 上一个ID颁发时间:{lastTimestamp});}//3: 确定自增序列号if(currentTimestamplastTimestamp){//确定是同一毫秒生成的IDsequence(sequence1)SEQUENCE_MASK;if(sequence0){//当前毫秒内自增序列号已经用完//阻塞等待下一毫秒tilNextMillis(currentTimestamp);}}else {sequence0;}//4:拼接结果lastTimestampcurrentTimestamp;return (currentTimestamp-START_TIMESTAMP)TIMESTAMP_SHIFT |(dataCenterDATA_CENTER_SHIFT)|(workIdWORK_ID_SHIFT)|(sequence);}/*** 当前毫秒内自增序列已经用完需要阻塞等待到下一毫秒* param lastTimestamp*/private void tilNextMillis(long lastTimestamp){long currentTimestamp currentTimestamp();while(currentTimestamplastTimestamp){currentTimestampcurrentTimestamp();}}/*** 获取系统当前的时间戳* return*/public long currentTimestamp(){return System.currentTimeMillis();}}问题一如果一个业务组下分布式ID发号器集群部署那么如何进行低成本的工作机器ID的配置 情况一机器集群规模较小时完全可以采用人工配置文件的方式进行配置。      情况二机器集群规模较大时如果采用人工配置和维护机器的工作ID成本过高。可以采用机器启动时向 zookeeper 注册持久且有序的节点。 机器启动顺序如下 1. 向zookeeper检查是否注册过。 2. 如果注册过获取节点的序列编号如果没有注册过则进行注册并获取序列ID。 3. 以获取的序列ID作为机器的工作ID启动。 问题二自增序列号是否会成为雪花算法的性能瓶颈 雪花算法的自增序列号占12bit位限制了雪花算法在1ms内最多生成4096个ID这似乎成为的雪花算法性能的上限。      但是现有的雪花算法性能已经很高了经测试SnowFlake单机可以每秒能够产生26万ID左右。这几乎已经满足了绝大多数实际的生产环境所需一般来说其性能已经完全够用了所以说自增序列号的限制不会成为雪花算法的性能瓶颈。 问题三如何打破雪花算法性能的瓶颈呢 基于“二八原则”80%的并发在20%的时间内产生按照这样的计算其实一天并发量主要集中在5个小时中也就是说并不是每时每刻都需要生成分布式ID且在同一个ms内其自增序列号很多时候也没有用完。也就是说并没有抓住每一个时刻生成分布式ID那么其性能自然会有上限。      那么解决方案就简单了如果能充分利用每一个时刻生成分布式ID那么其QPS上限能轻松达到百万量级。百度的 UidGenerator 采用了向未来借时间的思路打破了雪花算法性能的瓶颈。 问题四 雪花算法如何解决时针回拨的问题呢 雪花算法的时间戳是基于系统时间生成的但系统时间和北京时间不一定一致可能会存在系统时间相较于北京时间走快了或者走慢了。        那么如果系统时间原先比北京时间走快了但系统自动校准会导致时针回拨时针一旦回拨就有可能出现重复的ID打破了雪花算法的全局唯一ID的性质属于致命性错误 时针一旦回拨几乎是无解的问题因为实际生产环境中不能冒着生成重复ID的风险继续进行服务。应当根据时针回拨的严重程度做出不同的解决方案。 当然实际生产环境有各种各样的处理时针回拨的解决方案但一切技术都应该服务于实际的业务场景所以应当根据实际的业务场景去定制化时针回拨的解决方案。以上方案仅仅作为参考。 雪花算法的优缺点如下  优点 1. 高性能经测试雪花算法单机每秒可生成高达26万个ID左右。可以支撑起整个公司业务每天亿级别的调用足以满足绝大多数实际业务场景。 2. 有序性整体上按照生成时间顺序递增排序是趋势递增的。 3. 安全性相较于自增ID或者数据库生成的方式雪花算法生成的ID是趋势递增的不会被测算出订单量等敏感数据可以作为订单ID支付流水记录ID等敏感数据的ID。 缺点 1. 雪花算法强依赖于时钟的准确性一旦时针回拨可能会造成服务不可用因此基于雪花算法的唯一ID生成器必须集群化部署避免因为单个或者某几个服务发生时针回拨从而造成依赖于分布式ID生成的服务发生雪崩。 这章主要讲了常见常用的分布式ID生成策略但在实际生产环境中分布式ID生成器在高可用高性能高拓展方面做了很多优化。下章主要讲解实际生产环境中的分布式唯一ID生成器如何基于这篇文章中提到的分布式ID生成策略搭建出能够在复杂分布式环境中满足“三高”的分布式唯一ID生成系统。
http://wiki.neutronadmin.com/news/177693/

相关文章:

  • 望城区网站建设wordpress 微站
  • 网站建设商务代表工作总结生态建筑建设公司网站
  • 网站空间是不是服务器网站建设公司 合肥
  • 如何让域名跳转网站网站开发按几年摊销
  • 风铃网站代做潍坊网站搜索引擎优化
  • 电子商务企业网站的推广方式加油站网站建设
  • 云南网站营销网站推广策划的思路包括哪些
  • 专做零食的网站C 如何做简易网站
  • 微信 wordpress搜索seo网站推广的目的包括哪个方面
  • 如何修改网站备案网站建设优化是什么鬼
  • 北京网站建站系统平台南宁seo网络推广
  • 手把手教你做网站 3公司注册地址跟办公地址不一致
  • 网站信任的体验如何做网站域名备案认证
  • 瑞安 网站建设培训做网站的图片大全
  • 忻州网站建设求职简历怀柔富阳网站建设
  • 网站备案和服务器备案吗百度app最新版本
  • 公司网站建设457216336免费的ai作图软件
  • 象山县住房建设局网站南通网站建设公司排名
  • 怎么做产品的网站云南省建设交易中心网站
  • 网站开发上海广州怎么找做网站的公司
  • 成都企业网站建设哪家好行业网站怎么建设
  • 灵宝网站制作工作室网站开发上市公司
  • wordpress 关闭站点如何在工商局网站上做网登
  • 做网站的标准流程手机网站建设制作教程视频
  • 做网站需要人员投资管理公司注册条件和要求
  • 广州天河区做网站阿里云虚拟主机做wordpress
  • 企业网站意思东莞关键词排名快速优化
  • 大理网站推广贵阳做网站好的公司
  • 以下不属于网站建设优化大连建设网官方网站
  • 中小企业网站建设开题报告网页设计代码的基本格式