snowflake

一口气说出 9种 分布式ID生成方式,面试官有点懵了

不羁的心 提交于 2020-02-27 12:24:53
前两天有个朋友给我发信息吐槽最近面试:“四哥,年前我在公司受点委屈一冲动就裸辞了,然后现在疫情严重两个多月还没找到工作,接了几个视频面试也都没下文。好多面试官问完一个问题,紧接着说还会其他解决方法吗? 能干活解决bug不就行了吗?那还得会多少种方法? ” 面试官应该是对应聘者的回答不太满意,他想听到一个他认为最优的解决方案,其实这无可厚非。同样一个bug,能用一行代码解决问题的人和用十行代码解决问题的人,你会选哪个入职?显而易见的事情!所以看待问题还是要从多个角度出发,每种方法都有各自的利弊。 一、为什么要用分布式ID? 在说分布式ID的具体实现之前,我们来简单分析一下为什么用分布式ID?分布式ID应该满足哪些特征? 1、什么是分布式ID? 拿MySQL数据库举个栗子: 在我们业务数据量不大的时候,单库单表完全可以支撑现有业务,数据再大一点搞个MySQL主从同步读写分离也能对付。 但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有 唯一ID 做标识。此时一个能够生成 全局唯一ID 的系统是非常必要的。那么这个 全局唯一ID 就叫 分布式ID 。 2、那么分布式ID需要满足那些条件? 全局唯一:必须保证ID是全局性唯一的,基本要求 高性能:高可用低延时

返沪第一天,学习不能断,工作还要继续

*爱你&永不变心* 提交于 2020-02-26 17:59:32
返沪第一天 今天是2020年02月19日,是我返沪第一天,早上的体温是36.5,晚上的体温为36.6. 呵呵 -- 正常 说起返沪,海囧有木有。 回沪需要多转(转车三次) 从家开车到高铁站(这可是我第一次开车上高速,虽然我是一个老司机了(驾照到手好多年了)),这速度有点慢哦 乘高铁到成都,高铁都是隔人坐的,人好少。 转地铁到机场(包地铁的感觉有点爽) 飞机是满坐的,疫情也没挡住大家返沪的热情 磁悬浮只有列车员一人,大城市有点点可怕的感觉(呵呵) 回到小区,填写信息,告知自动在家隔离十四天。 以上都是昨天的海囧啦,以下才是主场: 在老家期间,阅读完一本书(非技术的),带回的技术书就翻看了几章,开车可以上路了(驾照大学期间就拿了,但之后从未开过车)。 今天,还未起床,居委会就打电话确认让隔离。 请假也要工作 一个早上三个工作会议(一个项目进度汇报,一个项目任务分配,一个与小伙伴沟通),下午协助公司解决线上线下遇到的一些杂七杂八的技术和非技术的问题。 隔离也要学习 为什么需要分库分表?(学习获取资料) 海量数据,数据库遇到瓶颈时,就需要分库分表。 MySQL 在 InnoDB 存储引擎下创建的索引都是基于 B+ 树实现的,所以查询时的 I/O 次数很大程度取决于树的高度,随着 B+ 树的树高增高,I/O 次数增加,查询性能也就越差。 当我们面对一张海量数据的表时,通常有分区、NoSQL

Twitter的分布式自增ID算法snowflake (Java版)

妖精的绣舞 提交于 2020-02-25 22:58:05
概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。 有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。 而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移到Cassandra,因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。 结构 snowflake的结构如下(每部分用-分开): 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年),然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点) ,最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号) 一共加起来刚好64位,为一个Long型。(转换成字符串后长度最多19) snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高

一线大厂的分布式唯一ID生成方案是什么样的?

与世无争的帅哥 提交于 2020-02-25 17:31:38
【推荐】2020年最新Java电子书集合.pdf(吐血整理) >>> 一、前言 分布式系统中我们会对一些数据量大的业务进行分拆,如:用户表,订单表。因为数据量巨大一张表无法承接,就会对其进行分库分表。 但一旦涉及到分库分表,就会引申出分布式系统中唯一主键ID的生成问题,永不迁移数据和避免热点的文章中要求需要唯一ID的特性: 整个系统ID唯一 ID是数字类型,而且是趋势递增的 ID简短,查询效率快 什么是递增? 如:第一次生成的ID为12,下一次生成的ID是13,再下一次生成的ID是14。这个就是生成ID递增。 什么是趋势递增? 如:在一段时间内,生成的ID是递增的趋势。如:再一段时间内生成的ID在【0,1000】之间,过段时间生成的ID在【1000,2000】之间。但在【0-1000】区间内的时候,ID生成有可能第一次是12,第二次是10,第三次是14。 那有什么方案呢?往下看! 二、分布式ID的几种生成方案 2.1、UUID 这个方案是小伙伴们第一个能过考虑到的方案 优点: 代码实现简单。 本机生成,没有性能问题 因为是全球唯一的ID,所以迁移数据容易 缺点: 每次生成的ID是无序的,无法保证趋势递增 UUID的字符串存储,查询效率慢 存储空间大 ID本事无业务含义,不可读 应用场景: 类似生成token令牌的场景 不适用一些要求有趋势递增的ID场景

微课程 | 第十三课《全局序列视频演示》

妖精的绣舞 提交于 2020-01-07 01:59:33
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> https://v.youku.com/v_show/id_XNDQ5Mjg1ODk0OA==.html 上一期我们介绍了全局序列的原理,接下来我们通过视频来演示一下全局序列功能。我们来看一下这两种全局序列是怎么工作的。 时间戳算法 首先是 snowflake ,也就是所谓时间戳算法。 https://v.youku.com/v_show/id_XNDQ5Mjg2MTA2NA==.html 默认的是直接使用时间戳算法,在实际的使用中先设置一下。在 server.xml 里面有一个叫 sequnceHandlerType 的属性。值为 2 表示时间戳类型,其它数值在文档中有详细介绍。我们去配置一个有全局序列的表。tb_hash_sharding_er2 表里面的 autoIncrement 属性为 true。target 是用来配置的全局序列的。然后 snowflake 算法还有一个工作节点,它标识了机器的 ID 。在配置文件当中分别有两行配置。这两行是一个联合主键,只要在不同机器上,联合值就不一样,那么就实现了标识。登录一个 dble 的流量端口。查看刚刚建的表是空的。再看一下这张表的结构,一共是三行。第一行数据类型是 bigint ,因为 snowflake 是一个 64 位的整数。64 位的整数超过了一般

ID生成器手册

坚强是说给别人听的谎言 提交于 2019-12-27 16:05:20
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> ID生成器手册 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。此时一个能够生成全局唯一ID的系统是非常必要的。概括下来,那业务系统对ID号的要求有哪些呢? 需求 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。 单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求。 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则。 上述123对应三类不同的场景,3和4需求还是互斥的,无法使用同一个方案满足。 同时除了对ID号码自身的要求,业务还对ID号生成系统的可用性要求极高,想象一下,如果ID生成系统瘫痪,整个美团点评支付、优惠券发券、骑手派单等关键动作都无法执行,这就会带来一场灾难。 由此总结下一个ID生成系统应该做到如下几点: 平均延迟和TP999延迟都要尽可能低; 可用性5个9; 高QPS。 实现 UUID UUID

微课程 | 第十二课《全局序列介绍》

廉价感情. 提交于 2019-12-27 14:08:37
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> https://v.youku.com/v_show/id_XNDQ4NDYyOTE5Mg==.html 上一期我们进行了 hint 的简单介绍和演示。我们的基本功能就介绍到这里,下面介绍一些进阶功能。 全局序列 我们先来介绍一下全局序列,我们DBLE目前支持四种全局序列。说是四种,如果按照他的内核区分是两种,只不过这两种方式放在不同的载体里面成为了四种。 我们先看这两种大概是一个什么概念。 snowflake 右上角这种是 snowflake 的算法是 twitter 最早提出的,通过 long 型数字分段实现的。DBLE 上面对它稍微有一些细节上的调整,但是不影响他的基本概念,他是通过时间戳做一个全局序列。首先他是一个 41 位的时间戳,大家可以先算一下 2 的 41 次方大概是多少?我们这边有个结论。这个数字大小应该足够 69 年的毫秒级别使用。对于我们一般的系统来说,能够存活 79 年应该不太可能。69 年其实已经够用了,计算机诞生也就刚过 70 年,然后我在每个毫秒中又有一个 12 位的序列号,12 位序列号就是 2 的 12 次方,就是 4096,也就是一毫米支持 4096 个并发。我们转换成 QPS 的话,就是乘以 1000,乘以 1000 以后应该是一个四百万的一个吞吐量

分布式系统 in 2010s :存储之数据库篇

折月煮酒 提交于 2019-12-26 19:06:38
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 作者:黄东旭 经常思考一个问题,为什么我们需要分布式?很大程度或许是不得已而为之。如果摩尔定律不会失效,如果通过低成本的硬件就能解决互联网日益增长的计算存储需求,是不是我们也就不需要分布式了。 过去的二三十年,是一场软件工程师们自我拯救的,浩浩荡荡的革命。分布式技术的发展,深刻地改变了我们编程的模式,改变了我们思考软件的模式。通过随处可见的 X86 或者 Arm 机器,构建出一个无限扩展的计算以及存储能力,这是软件工程师最浪漫的自我救赎。 值 2019 年末,PingCAP 联合 InfoQ 共同策划出品“分布式系统前沿技术”专题, 邀请转转、Pulsar、微众银行、UCloud、知乎、贝壳金服等技术团队共同参与,从数据库、硬件、测试、运维等角度,共同探索这个古老领域的新生机。 无论哪个时代,存储都是一个重要的话题,今天先聊聊数据库。在过去的几年,数据库技术上出现了几个很明显的趋势。 存储和计算进一步分离 我印象中最早的存储-计算分离的尝试是 Snowflake,Snowflake 团队在 2016 年发表的论文 《The Snowflake Elastic Data Warehouse》 是近几年我读过的最好的大数据相关论文之一,尤其推荐阅读。Snowflake 的架构关键点是在无状态的计算节点 +

分布式ID的简单总结

依然范特西╮ 提交于 2019-12-21 23:26:25
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 简单总结一下流行的分布式id的实现方法 雪花算法 snowflake是twitter开源的分布式ID生成算法. 核心思想是:分布式ID固定是一个long型的数字,一个long型占8个字节,也就是64个bit,原始snowflake算法中对于bit的分配如下图: 第一个bit位是标识部分,在java中由于long的最高位是符号位,正数是0,负数是1,一般生成的ID为正数,所以固定为0 时间戳部分占41bit,这个是毫秒级的时间,一般实现上不会存储当前的时间戳,而是时间戳的差值(当前时间-固定的开始时间) 这样可以使产生的ID从更小值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年 工作机器id占10bit,这里比较灵活,比如,可以使用前5位作为数据中心机房标识,后5位作为单机房机器标识,可以部署1024个节点 序列号部分占12bit,支持同一毫秒内同一个节点可以生成4096个ID snowflake算法需要人工为每台机器去指定一个机器id,如果机器很多或者机器扩展时, 挨个配置肯定不太现实,而且类似docker容器的流行, 使得这个机器id已经不能狭隘地停留在“物理”层面上了, 应该把机器id扩展为当前“实例”的id,

细聊分布式ID的生成方法

青春壹個敷衍的年華 提交于 2019-12-17 09:24:16
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 需求缘起   几乎所有的业务系统,都有生成一个记录标识的需求,例如: 1. 消息标识:message-id 2. 订单标识:order-id 3. 帖子标识:tiezi-id   这个记录标识往往就是数据库中的唯一主键,数据库上会建立聚集索引(cluster index),即在物理存储上以这个字段排序。这个记录标识上的查询,往往又有分页或者排序的业务需求,例如: 1. 拉取最新的一页消息: SELECT message-id ORDER BY time LIMIT 100 2. 拉取最新的一页订单: SELECT order-id ORDER BY time LIMIT 100 3. 拉取最新的一页帖子: SELECT tiezi-id ORDER BY time LIMIT 100   所以往往要有一个time字段,并且在time字段上建立普通索引(non-cluster index).我们都知道普通索引存储的是实际记录的指针,其访问效率会比聚集索引慢,如果记录标识在生成时能够基本按照时间有序,则可以省去这个time字段的索引查询: SELECT message-id ORDER BY message-id LIMIT 100   再次强调,能这么做的前提是message-id的生成基本是趋势时间递增的