Allen

写代码是热爱,写到世界充满爱

  • HomePage
  • Categories
  • Archives
  • Essay
  • Tags
总文章数 379
所有文章 友链 关于我

Allen

写代码是热爱,写到世界充满爱

  • HomePage
  • Categories
  • Archives
  • Essay
  • Tags

分布式ID的花拳绣腿

阅读数:135次 2020-04-19
字数统计: 4.8k字   |   阅读时长: 20分

文章导航

× 文章目录
  1. 1. 1. 为什么要用分布式ID?
    1. 1.1. 1、什么是分布式ID?
    2. 1.2. 2、那么分布式ID需要满足那些条件?
  2. 2. 2. 分布式ID都有哪些生成方式?
    1. 2.1. 1. 基于UUID
    2. 2.2. 2. 基于数据库自增ID
    3. 2.3. 3. 基于数据库集群模式
    4. 2.4. 4. 基于数据库的号段模式
    5. 2.5. 5. 基于Redis模式
    6. 2.6. 6. 基于雪花算法(Snowflake)模式
    7. 2.7. 7. 百度(uid-generator)
    8. 2.8. 8. 美团(Leaf)
      1. 2.8.0.1. 号段模式
      2. 2.8.0.2. snowflake模式
  3. 2.9. 9. 滴滴(Tinyid)
    1. 2.9.0.1. Http方式接入
    2. 2.9.0.2. Java客户端方式接入
  • 3. 3. 小结
  • 转载自 原创作者 微信号-mhcoding

    1. 为什么要用分布式ID?

    在说分布式ID的具体实现之前,我们来简单分析一下为什么用分布式ID?分布式ID应该满足哪些特征?

    1、什么是分布式ID?

    拿MySQL数据库举个栗子:

    在我们业务数据量不大的时候,单库单表完全可以支撑现有业务,数据再大一点搞个MySQL主从同步读写分离也能对付。

    但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID。

    2、那么分布式ID需要满足那些条件?

    • 全局唯一:必须保证ID是全局性唯一的,基本要求

    • 高性能:高可用低延时,ID生成响应要块,否则反倒会成为业务瓶颈

    • 高可用:100%的可用性是骗人的,但是也要无限接近于100%的可用性

    • 好接入:要秉着拿来即用的设计原则,在系统设计和实现上要尽可能的简单

    • 趋势递增:最好趋势递增,这个要求就得看具体业务场景了,一般不严格要求

    2. 分布式ID都有哪些生成方式?

    今天主要分析一下以下9种,分布式ID生成器方式以及优缺点:

    • UUID

    • 数据库自增ID

    • 数据库多主模式

    • 号段模式

    • Redis

    • 雪花算法(SnowFlake)

    • 滴滴出品(TinyID)

    • 百度 (Uidgenerator)

    • 美团(Leaf)

    那么它们都是如何实现?以及各自有什么优缺点?我们往下看

    1. 基于UUID

    在Java的世界里,想要得到一个具有唯一性的ID,首先被想到可能就是UUID,毕竟它有着全球唯一的特性。那么UUID可以做分布式ID吗?答案是可以的,但是并不推荐!

    1
    2
    3
    4
    public static void main(String[] args) { 
    String uuid = UUID.randomUUID().toString().replaceAll("-","");
    System.out.println(uuid);
    }

    UUID的生成简单到只有一行代码,输出结果 c2b8c2b9e46c47e3b30dca3b0d447718,但UUID却并不适用于实际的业务需求。像用作订单号UUID这样的字符串没有丝毫的意义,看不出和订单相关的有用信息;而对于数据库来说用作业务主键ID,它不仅是太长还是字符串,存储性能差查询也很耗时,所以不推荐用作分布式ID。

    优点:

    • 生成足够简单,本地生成无网络消耗,具有唯一性

    缺点:

    • 无序的字符串,不具备趋势自增特性

    • 没有具体的业务含义

    • 长度过长16 字节128位,36位长度的字符串,存储以及查询对MySQL的性能消耗较大,MySQL官方明确建议主键要尽量越短越好,作为数据库主键 UUID 的无序性会导致数据位置频繁变动,严重影响性能。

    2. 基于数据库自增ID

    基于数据库的auto_increment自增ID完全可以充当分布式ID,具体实现:需要一个单独的MySQL实例用来生成ID,建表结构如下:

    1
    2
    3
    4
    5
    6
    7
    8
    CREATE DATABASE `SEQ_ID`;
    CREATE TABLE SEQID.SEQUENCE_ID (
    id bigint(20) unsigned NOT NULL auto_increment,
    value char(10) NOT NULL default '',
    PRIMARY KEY (id),
    ) ENGINE=MyISAM;

    insert into SEQUENCE_ID(value) VALUES ('values');

    当我们需要一个ID的时候,向表中插入一条记录返回主键ID,但这种方式有一个比较致命的缺点,访问量激增时MySQL本身就是系统的瓶颈,用它来实现分布式服务风险比较大,不推荐!

    优点:

    • 实现简单,ID单调自增,数值类型查询速度快

    缺点:

    • DB单点存在宕机风险,无法扛住高并发场景

    3. 基于数据库集群模式

    前边说了单点数据库方式不可取,那对上边的方式做一些高可用优化,换成主从模式集群。害怕一个主节点挂掉没法用,那就做双主模式集群,也就是两个Mysql实例都能单独的生产自增ID。

    那这样还会有个问题,两个MySQL实例的自增ID都从1开始,会生成重复的ID怎么办?

    解决方案:设置起始值和自增步长

    MySQL_1 配置:

    1
    2
    set @@auto_increment_offset = 1;     -- 起始值
    set @@auto_increment_increment = 2; -- 步长

    MySQL_2 配置:

    1
    2
    set @@auto_increment_offset = 2;     -- 起始值
    set @@auto_increment_increment = 2; -- 步长

    这样两个MySQL实例的自增ID分别就是:

    1、3、5、7、9
    2、4、6、8、10

    那如果集群后的性能还是扛不住高并发咋办?就要进行MySQL扩容增加节点,这是一个比较麻烦的事。

    从上图可以看出,水平扩展的数据库集群,有利于解决数据库单点压力的问题,同时为了ID生成特性,将自增步长按照机器数量来设置。

    增加第三台MySQL实例需要人工修改一、二两台MySQL实例的起始值和步长,把第三台机器的ID起始生成位置设定在比现有最大自增ID的位置远一些,但必须在一、二两台MySQL实例ID还没有增长到第三台MySQL实例的起始ID值的时候,否则自增ID就要出现重复了,必要时可能还需要停机修改。

    优点:

    • 解决DB单点问题

    缺点:

    • 不利于后续扩容,而且实际上单个数据库自身压力还是大,依旧无法满足高并发场景。

    4. 基于数据库的号段模式

    号段模式是当下分布式ID生成器的主流实现方式之一,号段模式可以理解为从数据库批量的获取自增ID,每次从数据库取出一个号段范围,例如 (1,1000] 代表1000个ID,具体的业务服务将本号段,生成1~1000的自增ID并加载到内存。表结构如下:

    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE id_generator (
    id int(10) NOT NULL,
    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`)
    )

    biz_type :代表不同业务类型

    max_id :当前最大的可用id

    step :代表号段的长度

    version :是一个乐观锁,每次都更新version,保证并发时数据的正确性

    等这批号段ID用完,再次向数据库申请新号段,对max_id字段做一次update操作,update max_id= max_id + step,update成功则说明新号段获取成功,新的号段范围是(max_id ,max_id +step]。

    1
    update id_generator set max_id = #{max_id+step}, version = version + 1 where version = # {version} and biz_type = XXX

    由于多业务端可能同时操作,所以采用版本号version乐观锁方式更新,这种分布式ID生成方式不强依赖于数据库,不会频繁的访问数据库,对数据库的压力小很多。

    5. 基于Redis模式

    Redis也同样可以实现,原理就是利用redis的 incr命令实现ID的原子性自增。

    1
    2
    3
    4
    127.0.0.1:6379> set seq_id 1     // 初始化自增ID为1
    OK
    127.0.0.1:6379> incr seq_id // 增加1,并返回递增后的数值
    (integer) 2

    用redis实现需要注意一点,要考虑到redis持久化的问题。redis有两种持久化方式RDB和AOF

    • RDB会定时打一个快照进行持久化,假如连续自增但redis没及时持久化,而这会Redis挂掉了,重启Redis后会出现ID重复的情况。

    • AOF会对每条写命令进行持久化,即使Redis挂掉了也不会出现ID重复的情况,但由于incr命令的特殊性,会导致Redis重启恢复的数据时间过长。

    6. 基于雪花算法(Snowflake)模式

    雪花算法(Snowflake)是twitter公司内部分布式项目采用的ID生成算法,开源后广受国内大厂的好评,在该算法影响下各大公司相继开发出各具特色的分布式生成器。

    Snowflake生成的是Long类型的ID,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特。

    Snowflake ID组成结构:正数位(占1比特)+ 时间戳(占41比特)+ 机器ID(占5比特)+ 数据中心(占5比特)+ 自增值(占12比特),总共64比特组成的一个Long类型。

    • 第一个bit位(1bit):Java中long的最高位是符号位代表正负,正数是0,负数是1,一般生成ID都为正数,所以默认为0。

    • 时间戳部分(41bit):毫秒级的时间,不建议存当前时间戳,而是用(当前时间戳 - 固定开始时间戳)的差值,可以使产生的ID从更小的值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年

    • 工作机器id(10bit):也被叫做workId,这个可以灵活配置,机房或者机器号组合都可以。

    • 序列号部分(12bit),自增值支持同一毫秒内同一个节点可以生成4096个ID

    根据这个算法的逻辑,只需要将这个算法用Java语言实现出来,封装为一个工具方法,那么各个业务应用可以直接使用该工具方法来获取分布式ID,只需保证每个业务应用有自己的工作机器id即可,而不需要单独去搭建一个获取分布式ID的应用。

    Java版本的**Snowflake算法实现:**

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    /**
    * Twitter的SnowFlake算法,使用SnowFlake算法生成一个整数,然后转化为62进制变成一个短地址URL
    *
    */
    public class SnowFlakeShortUrl {

    /**
    * 起始的时间戳
    */
    private final static long START_TIMESTAMP = 1480166465631L;

    /**
    * 每一部分占用的位数
    */
    private final static long SEQUENCE_BIT = 12; //序列号占用的位数
    private final static long MACHINE_BIT = 5; //机器标识占用的位数
    private final static long DATA_CENTER_BIT = 5; //数据中心占用的位数

    /**
    * 每一部分的最大值
    */
    private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
    private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private final static long MAX_DATA_CENTER_NUM = -1L ^ (-1L << DATA_CENTER_BIT);

    /**
    * 每一部分向左的位移
    */
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long DATA_CENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private final static long TIMESTAMP_LEFT = DATA_CENTER_LEFT + DATA_CENTER_BIT;

    private long dataCenterId; //数据中心
    private long machineId; //机器标识
    private long sequence = 0L; //序列号
    private long lastTimeStamp = -1L; //上一次时间戳

    private long getNextMill() {
    long mill = getNewTimeStamp();
    while (mill <= lastTimeStamp) {
    mill = getNewTimeStamp();
    }
    return mill;
    }

    private long getNewTimeStamp() {
    return System.currentTimeMillis();
    }

    /**
    * 根据指定的数据中心ID和机器标志ID生成指定的序列号
    *
    * @param dataCenterId 数据中心ID
    * @param machineId 机器标志ID
    */
    public SnowFlakeShortUrl(long dataCenterId, long machineId) {
    if (dataCenterId > MAX_DATA_CENTER_NUM || dataCenterId < 0) {
    throw new IllegalArgumentException("DtaCenterId can't be greater than MAX_DATA_CENTER_NUM or less than 0!");
    }
    if (machineId > MAX_MACHINE_NUM || machineId < 0) {
    throw new IllegalArgumentException("MachineId can't be greater than MAX_MACHINE_NUM or less than 0!");
    }
    this.dataCenterId = dataCenterId;
    this.machineId = machineId;
    }

    /**
    * 产生下一个ID
    *
    * @return
    */
    public synchronized long nextId() {
    long currTimeStamp = getNewTimeStamp();
    if (currTimeStamp < lastTimeStamp) {
    throw new RuntimeException("Clock moved backwards. Refusing to generate id");
    }

    if (currTimeStamp == lastTimeStamp) {
    //相同毫秒内,序列号自增
    sequence = (sequence + 1) & MAX_SEQUENCE;
    //同一毫秒的序列数已经达到最大
    if (sequence == 0L) {
    currTimeStamp = getNextMill();
    }
    } else {
    //不同毫秒内,序列号置为0
    sequence = 0L;
    }

    lastTimeStamp = currTimeStamp;

    return (currTimeStamp - START_TIMESTAMP) << TIMESTAMP_LEFT //时间戳部分
    | dataCenterId << DATA_CENTER_LEFT //数据中心部分
    | machineId << MACHINE_LEFT //机器标识部分
    | sequence; //序列号部分
    }

    public static void main(String[] args) {
    SnowFlakeShortUrl snowFlake = new SnowFlakeShortUrl(2, 3);

    for (int i = 0; i < (1 << 4); i++) {
    //10进制
    System.out.println(snowFlake.nextId());
    }
    }
    }

    7. 百度(uid-generator)

    uid-generator是由百度技术部开发,项目GitHub地址 https://github.com/baidu/uid-generator

    uid-generator是基于Snowflake算法实现的,与原始的snowflake算法不同在于,uid-generator支持自定义时间戳、工作机器ID和 序列号 等各部分的位数,而且uid-generator中采用用户自定义workId的生成策略。

    uid-generator需要与数据库配合使用,需要新增一个WORKER_NODE表。当应用启动时会向数据库表中去插入一条数据,插入成功后返回的自增ID就是该机器的workId数据由host,port组成。

    对于uid-generator ID组成结构:

    workId,占用了22个bit位,时间占用了28个bit位,序列化占用了13个bit位,需要注意的是,和原始的snowflake不太一样,时间的单位是秒,而不是毫秒,workId也不一样,而且同一应用每次重启就会消费一个workId。

    参考文献
    https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md

    8. 美团(Leaf)

    Leaf由美团开发,github地址:https://github.com/Meituan-Dianping/Leaf

    Leaf同时支持号段模式和snowflake算法模式,可以切换使用。

    号段模式

    先导入源码 https://github.com/Meituan-Dianping/Leaf ,在建一张表leaf_alloc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    DROP TABLE IF EXISTS `leaf_alloc`;

    CREATE TABLE `leaf_alloc` (
    `biz_tag` varchar(128) NOT NULL DEFAULT '' COMMENT '业务key',
    `max_id` bigint(20) NOT NULL DEFAULT '1' COMMENT '当前已经分配了的最大id',
    `step` int(11) NOT NULL COMMENT '初始步长,也是动态调整的最小步长',
    `description` varchar(256) DEFAULT NULL COMMENT '业务key的描述',
    `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据库维护的更新时间',
    PRIMARY KEY (`biz_tag`)
    ) ENGINE=InnoDB;

    然后在项目中开启号段模式,配置对应的数据库信息,并关闭snowflake模式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    leaf.name=com.sankuai.leaf.opensource.test
    leaf.segment.enable=true
    leaf.jdbc.url=jdbc:mysql://localhost:3306/leaf_test?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    leaf.jdbc.username=root
    leaf.jdbc.password=root

    leaf.snowflake.enable=false
    #leaf.snowflake.zk.address=
    #leaf.snowflake.port=

    启动leaf-server 模块的 LeafServerApplication项目就跑起来了

    号段模式获取分布式自增ID的测试url :http://localhost:8080/api/segment/get/leaf-segment-test

    监控号段模式:http://localhost:8080/cache

    snowflake模式

    Leaf的snowflake模式依赖于ZooKeeper,不同于原始snowflake算法也主要是在workId的生成上,Leaf中workId是基于ZooKeeper的顺序Id来生成的,每个应用在使用Leaf-snowflake时,启动时都会都在Zookeeper中生成一个顺序Id,相当于一台机器对应一个顺序节点,也就是一个workId。

    1
    2
    3
    leaf.snowflake.enable=true
    leaf.snowflake.zk.address=127.0.0.1
    leaf.snowflake.port=2181

    snowflake模式获取分布式自增ID的测试url:http://localhost:8080/api/snowflake/get/test

    9. 滴滴(Tinyid)

    Tinyid由滴滴开发,Github地址:https://github.com/didi/tinyid。

    Tinyid是基于号段模式原理实现的与Leaf如出一辙,每个服务获取一个号段(1000,2000]、(2000,3000]、(3000,4000]

    Tinyid提供http和tinyid-client两种方式接入

    Http方式接入

    (1)导入Tinyid源码:

    git clone https://github.com/didi/tinyid.git

    (2)创建数据表:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    CREATE TABLE `tiny_id_info` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
    `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '业务类型,唯一',
    `begin_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '开始id,仅记录初始值,无其他含义。初始化时begin_id和max_id应相同',
    `max_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '当前最大id',
    `step` int(11) DEFAULT '0' COMMENT '步长',
    `delta` int(11) NOT NULL DEFAULT '1' COMMENT '每次id增量',
    `remainder` int(11) NOT NULL DEFAULT '0' COMMENT '余数',
    `create_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '创建时间',
    `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新时间',
    `version` bigint(20) NOT NULL DEFAULT '0' COMMENT '版本号',
    PRIMARY KEY (`id`),
    UNIQUE KEY `uniq_biz_type` (`biz_type`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'id信息表';

    CREATE TABLE `tiny_id_token` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
    `token` varchar(255) NOT NULL DEFAULT '' COMMENT 'token',
    `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '此token可访问的业务类型标识',
    `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
    `create_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '创建时间',
    `update_time` timestamp NOT NULL DEFAULT '2010-01-01 00:00:00' COMMENT '更新时间',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'token信息表';

    INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
    VALUES
    (1, 'test', 1, 1, 100000, 1, 0, '2018-07-21 23:52:58', '2018-07-22 23:19:27', 1);

    INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
    VALUES
    (2, 'test_odd', 1, 1, 100000, 2, 1, '2018-07-21 23:52:58', '2018-07-23 00:39:24', 3);

    INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
    VALUES
    (1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48');

    INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
    VALUES
    (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', '2017-12-14 16:36:46', '2017-12-14 16:36:48');

    (3)配置数据库:

    1
    2
    3
    4
    5
    datasource.tinyid.names=primary
    datasource.tinyid.primary.driver-class-name=com.mysql.jdbc.Driver
    datasource.tinyid.primary.url=jdbc:mysql://ip:port/databaseName?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
    datasource.tinyid.primary.username=root
    datasource.tinyid.primary.password=123456

    (4)启动tinyid-server后测试

    1
    2
    3
    4
    5
    6
    获取分布式自增ID: http://localhost:9999/tinyid/id/nextIdSimple?bizType=test&token=0f673adf80504e2eaa552f5d791b644c'
    返回结果: 3

    批量获取分布式自增ID:
    http://localhost:9999/tinyid/id/nextIdSimple?bizType=test&token=0f673adf80504e2eaa552f5d791b644c&batchSize=10'
    返回结果: 4,5,6,7,8,9,10,11,12,13
    Java客户端方式接入

    重复Http方式的(2)(3)操作

    引入依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>com.xiaoju.uemc.tinyid</groupId>
    <artifactId>tinyid-client</artifactId>
    <version>${tinyid.version}</version>
    </dependency>

    配置文件

    1
    2
    tinyid.server =localhost:9999
    tinyid.token =0f673adf80504e2eaa552f5d791b644c

    test 、tinyid.token是在数据库表中预先插入的数据,test 是具体业务类型,tinyid.token表示可访问的业务类型

    1
    2
    3
    4
    5
    // 获取单个分布式自增ID
    Long id = TinyId . nextId( " test " );

    // 按需批量分布式自增ID
    List< Long > ids = TinyId . nextId( " test " , 10 );

    3. 小结

    每种生成方式都有它自己的优缺点,具体如何使用还要看具体的业务需求。

    • 面试
    • 系统架构
    • 分布式
    • 分布式
    • 面试
    • 系统架构

    扫一扫,分享到微信

    微信分享二维码
    FaaS-又一个为未来
    4-Dockerfile上
    1. 1. 1. 为什么要用分布式ID?
      1. 1.1. 1、什么是分布式ID?
      2. 1.2. 2、那么分布式ID需要满足那些条件?
    2. 2. 2. 分布式ID都有哪些生成方式?
      1. 2.1. 1. 基于UUID
      2. 2.2. 2. 基于数据库自增ID
      3. 2.3. 3. 基于数据库集群模式
      4. 2.4. 4. 基于数据库的号段模式
      5. 2.5. 5. 基于Redis模式
      6. 2.6. 6. 基于雪花算法(Snowflake)模式
      7. 2.7. 7. 百度(uid-generator)
      8. 2.8. 8. 美团(Leaf)
        1. 2.8.0.1. 号段模式
        2. 2.8.0.2. snowflake模式
    3. 2.9. 9. 滴滴(Tinyid)
      1. 2.9.0.1. Http方式接入
      2. 2.9.0.2. Java客户端方式接入
  • 3. 3. 小结
  • Related Issues not found

    Please contact @JavaSsun to initialize the comment

    © 2018-2024 Allen
    Hexo Theme Yilia by Litten
    本站总访问量72056次 | 本站访客数64742人
    • 所有文章
    • 友链
    • 关于我

    tag:

    • Elasticsearch
    • 面试
    • MQ
    • Redis
    • Nginx
    • Docker
    • Git
    • Dubbo
    • 论文
    • MySql
    • Tools
    • 日志
    • Linux
    • 系统架构
    • Java
    • 源码解析
    • Hexo-yilia
    • Jvm
    • MyBatis
    • SpringBoot
    • Swagger2
    • 算法
    • 分布式
    • Photo
    • HTTP
    • Hystrix
    • SSL
    • ELK
    • IDEA
    • Jwt
    • 定时任务
    • BigData
    • Maven
    • Quartz
    • 人工智能
    • 地图坐标转换
    • 网络编程
    • Python
    • SpringCloud
    • 搬砖结晶
    • OpenCV
    • 推荐系统
    • 目标检测
    • SkLearn
    • 图神经网络
    • PyTorch
    • TensorFlow
    • 数据挖掘
    • 研究生课题-AD检测
    • 研究生成果

      缺失模块。
      1、请确保node版本大于6.2
      2、在博客根目录(注意不是yilia根目录)执行以下命令:
      npm i hexo-generator-json-content --save

      3、在根目录_config.yml里添加配置:

        jsonContent:
          meta: false
          pages: false
          posts:
            title: true
            date: true
            path: true
            text: false
            raw: false
            content: false
            slug: false
            updated: false
            comments: false
            link: false
            permalink: false
            excerpt: false
            categories: false
            tags: true
      

    • 研究生总结

      2024-05-09

      #论文#人工智能#搬砖结晶#图神经网络#研究生课题-AD检测#研究生成果

    • 12-ROI文件分析

      2023-11-22

      #Tools#人工智能#研究生课题-AD检测

    • 11-DTI预处理

      2023-11-16

      #Tools#人工智能#研究生课题-AD检测

    • 10-GRETNA处理fMRI

      2023-11-05

      #Tools#人工智能#研究生课题-AD检测

    • 9-(图)利用Matlab的spm12工具处理fMRI为ROI

      2023-10-28

      #Tools#人工智能#研究生课题-AD检测

    • 9-(文)利用Matlab的spm12工具处理fMRI为ROI

      2023-10-26

      #Tools#人工智能#研究生课题-AD检测

    • 8-7-FSL软件使用

      2023-10-20

      #Tools#人工智能#研究生课题-AD检测

    • 8-6-FreeSurfer软件使用

      2023-10-16

      #Tools#人工智能#研究生课题-AD检测

    • 8-5-SPM软件使用

      2023-10-10

      #Tools#人工智能#研究生课题-AD检测

    • 8-4-MRI预处理

      2023-09-16

      #Tools#人工智能#研究生课题-AD检测

    • 8-3-UNet提取海马体

      2023-09-10

      #人工智能#研究生课题-AD检测

    • 8-2-ADNI论文数据预处理

      2023-09-02

      #论文#Tools#人工智能#研究生课题-AD检测

    • 8-1-数据预处理工具

      2023-08-05

      #Tools#人工智能#研究生课题-AD检测

    • 7-2-GNN For AD

      2023-07-25

      #论文#人工智能#图神经网络#研究生课题-AD检测

    • 7-1-GNN For Medical Diagnosis

      2023-06-28

      #论文#人工智能#图神经网络#研究生课题-AD检测

    • 6-2-SCI一区论文精读

      2023-05-25

      #论文#人工智能#研究生课题-AD检测

    • 6-1-MRI成像及ADNI简介

      2023-05-10

      #人工智能#研究生课题-AD检测

    • 5-ADNI-实验数据筛选与下载

      2023-04-25

      #人工智能#研究生课题-AD检测

    • 4-AD文献的阅读记录

      2023-04-20

      #论文#人工智能#研究生课题-AD检测

    • 3-指标特征选择

      2023-04-05

      #人工智能#研究生课题-AD检测

    • 2-AD有关课题

      2023-03-25

      #人工智能#研究生课题-AD检测

    • 1-阿尔茨海默病

      2023-03-20

      #人工智能#研究生课题-AD检测

    • 7-SHAP

      2023-03-15

      #人工智能#数据挖掘

    • 6-模型的融合技术大总结与结果部署

      2023-02-25

      #人工智能#数据挖掘

    • 5-模型建立与调参

      2023-02-20

      #人工智能#数据挖掘

    • 4-特征工程

      2023-02-12

      #人工智能#数据挖掘

    • 3-数据清洗和转换技巧

      2023-02-09

      #人工智能#数据挖掘

    • 2-数据的探索性-EDA分析

      2023-02-06

      #人工智能#数据挖掘

    • 1-赛题理解

      2023-02-04

      #人工智能#数据挖掘

    • 0-零基础入门数据挖掘学习路径

      2023-02-03

      #人工智能#数据挖掘

    • 重温深度学习优化算法

      2023-01-28

      #人工智能

    • 重温归一化(MinMaxScaler)和标准化(StandardScaler)

      2023-01-20

      #人工智能

    • 重温Batch Normalization

      2023-01-15

      #人工智能

    • 交叉熵损失函数和平方损失的区别

      2023-01-12

      #人工智能

    • loss不下降的解决方法

      2023-01-10

      #人工智能

    • 重温Seq2Seq和Attention机制

      2023-01-05

      #人工智能

    • 重温LSTM和GRU

      2022-12-28

      #人工智能

    • 重温RNN

      2022-12-25

      #人工智能

    • pytorch_geometric离线安装

      2022-12-19

      #人工智能#图神经网络#PyTorch

    • pytorch_geometric安装

      2022-12-18

      #人工智能#图神经网络#PyTorch

    • 生成式对抗网络GAN的工作原理

      2022-12-13

      #人工智能

    • Ubuntu查看cuda-cudnn等版本命令

      2022-12-10

      #Tools#人工智能

    • CUDA和CuDNN安装

      2022-12-08

      #Tools#人工智能

    • GPU之nvidia-smi命令详解

      2022-12-05

      #Tools#人工智能

    • 1-TensorFlow简介及安装

      2022-12-01

      #人工智能#TensorFlow

    • 入门图神经网络

      2022-11-25

      #人工智能#图神经网络

    • 10-模型的保存加载-模型微调-GPU使用及Pytorch常见报错

      2022-11-06

      #人工智能#PyTorch

    • 9-正则化与标准化大总结

      2022-10-28

      #人工智能#PyTorch

    • 8-Tensorboard可视化与Hook机制

      2022-10-25

      #人工智能#PyTorch

    • 7-优化器和学习率调整策略

      2022-10-23

      #人工智能#PyTorch

    • 6-模型的权值初始化与损失函数介绍

      2022-10-20

      #人工智能#PyTorch

    • 5-nn各网络层介绍

      2022-10-17

      #人工智能#PyTorch

    • Pytorch提取神经网络层结构-层参数及自定义初始化

      2022-10-14

      #人工智能#PyTorch

    • 4-模型创建Module-模型容器Containers及AlexNet网络搭建

      2022-10-12

      #人工智能#PyTorch

    • 3-Pytorch数据读取机制(DataLoader)与图像预处理模块(transforms)

      2022-10-09

      #人工智能#PyTorch

    • 2-Pytorch的动态图-自动求导及逻辑回归

      2022-10-02

      #人工智能#PyTorch

    • 1-Pytorch的数据载体张量与线性回归

      2022-09-28

      #人工智能#PyTorch

    • Pytorch与词向量

      2022-09-25

      #人工智能#PyTorch

    • Pytorch基础理论和简单的神经网络实现

      2022-09-23

      #人工智能#PyTorch

    • Windows下的Pytorch环境搭建

      2022-09-20

      #人工智能#PyTorch

    • 图卷积网络-GCN

      2022-09-15

      #人工智能#图神经网络

    • GCN使用的数据集Cora等

      2022-09-10

      #人工智能#图神经网络

    • 图网络属性介绍

      2022-09-08

      #人工智能#图神经网络

    • 图神经网络理论基础

      2022-09-05

      #人工智能#图神经网络

    • 5-AI上推荐之AutoRec与Deep Crossing模型(改变神经网络的复杂程度)

      2022-08-28

      #人工智能#推荐系统

    • 4-AI上推荐之FM和FFM(九九归一)

      2022-08-17

      #人工智能#推荐系统

    • 梯度提升树GBDT的理论学习与细节补充

      2022-08-05

      #人工智能#推荐系统

    • 梯度下降算法的细节补充(凸函数, 导数, 偏导数,梯度, 方向导数以及负梯度下降最快背后的泰勒身影)

      2022-07-28

      #人工智能#推荐系统

    • 逻辑回归、优化算法和正则化的幕后细节补充

      2022-07-24

      #人工智能#推荐系统

    • 3-AI上推荐之逻辑回归模型与GBDT+LR(特征工程模型化的开端)

      2022-07-20

      #人工智能#推荐系统

    • 奇异值分解(SVD)的原理详解及推导

      2022-07-13

      #人工智能#推荐系统

    • 2-AI上推荐之隐语义模型(LFM)和矩阵分解(MF)

      2022-07-10

      #人工智能#推荐系统

    • 1-AI上推荐之协同过滤

      2022-07-02

      #人工智能#推荐系统

    • R-CNN and Fast R-CNN and Faster R-CNN and SPP

      2022-06-15

      #人工智能#目标检测

    • 10-Harris和Shi-Tomas算法

      2022-06-06

      #人工智能#OpenCV

    • 9-角点特征

      2022-06-03

      #人工智能#OpenCV

    • 8-图像变换-傅里叶变换

      2022-05-29

      #人工智能#OpenCV

    • 7-模板匹配与霍夫变换

      2022-05-15

      #人工智能#OpenCV

    • 6-边缘检测

      2022-05-08

      #人工智能#OpenCV

    • 5-直方图

      2022-04-28

      #人工智能#OpenCV

    • 4-图像平滑

      2022-04-26

      #人工智能#OpenCV

    • 3-形态学操作

      2022-04-22

      #人工智能#OpenCV

    • 2-几何变换

      2022-04-20

      #人工智能#OpenCV

    • 1-图像的基础操作

      2022-04-18

      #人工智能#OpenCV

    • 0-OpenCV简介

      2022-04-15

      #人工智能#OpenCV

    • Ubuntu18.04下安装OpenCV3.4

      2022-04-01

      #人工智能#OpenCV

    • 后 R-CNN时代, Faster R-CNN、SSD、YOLO 各类变体统治下的目标检测综述:Faster R-CNN系列胜了吗?

      2022-03-28

      #人工智能#目标检测

    • SKLearn学习总结

      2022-03-20

      #人工智能#SkLearn

    • 详细了解PyCharm支持的4种Python Interpreter和配置方法

      2022-03-02

      #Tools

    • Pycharm远程连接

      2022-02-26

      #Tools

    • JupyterLab学习总结

      2022-02-19

      #Tools#人工智能

    • Anaconda学习总结

      2022-02-13

      #Tools#人工智能

    • Ubuntu下安装lrzsz工具

      2022-02-08

      #Tools

    • 13-RNN

      2022-02-05

      #人工智能

    • 12-加速深度学习的算法和硬件-讲座

      2022-01-10

      #人工智能

    • 11-深度学习硬件算力基础-GPU与TPU与英特尔神经棒

      2021-12-26

      #人工智能

    • 10-经典卷积神经网络架构案例分析

      2021-12-16

      #人工智能

    • 9-迁移学习与fine-tuning

      2021-12-11

      #人工智能

    • 8-CNNS in Practice-卷积神经网络工程实践技巧

      2021-11-28

      #人工智能

    • 7-训练神经网络-下

      2021-11-09

      #人工智能

    • 6-训练神经网络-上

      2021-11-05

      #人工智能

    • 5-可视化并理解卷积神经网络

      2021-10-25

      #人工智能

    • 4-Convolutional-Neural-Networks

      2021-10-18

      #人工智能

    • 3-神经网络与反向传播

      2021-10-10

      #人工智能

    • 2-损失函数和梯度下降

      2021-09-25

      #人工智能

    • 1-KNN&线性分类器

      2021-09-20

      #人工智能

    • 0-机器学习基础

      2021-09-15

      #人工智能

    • 入门人工智能算法工程师-先来碗毒鸡汤

      2021-07-30

      #人工智能

    • 3-如何高效阅读机器学习顶会论文

      2021-07-15

      #论文

    • 2-论文ABC类与一二区的区别

      2021-06-10

      #论文

    • 1-学术小白

      2021-06-06

      #论文

    • 领域驱动设计在互联网业务开发中的实践

      2020-09-13

      #系统架构

    • 领域驱动设计

      2020-07-12

      #系统架构

    • DDD模式-从天书到实践

      2020-06-28

      #系统架构

    • DDD-马什么梅

      2020-06-14

      #系统架构

    • FaaS-又一个为未来

      2020-05-17

      #系统架构

    • 分布式ID的花拳绣腿

      2020-04-19

      #面试#系统架构#分布式

    • 4-Dockerfile上

      2020-04-08

      #Docker

    • 3-Docker存储卷

      2020-04-07

      #Docker

    • 2-Docker容器网络

      2020-04-06

      #Docker

    • 1-安装_使用Docker

      2020-04-05

      #Docker

    • 45-自增ID用完怎么办

      2020-03-11

      #MySql

    • 44-一些常见问题

      2020-03-09

      #MySql

    • 43-要不要使用分区表

      2020-03-08

      #MySql

    • 42-grant之后要跟着flush privileges吗

      2020-03-07

      #MySql

    • 41-如何最快的复制一张表

      2020-03-06

      #MySql

    • 40-insert语句的锁为什么这么多

      2020-03-04

      #MySql

    • 39-自增主键为什么不是连续的

      2020-03-03

      #MySql

    • 38-都说InnoDB好_那还要不要使用Memory引擎

      2020-03-02

      #MySql

    • 37-什么时候会使用内部临时表

      2020-03-01

      #MySql

    • SpringBoot_RabbitMQ配置参数详解

      2020-02-26

      #MQ

    • RabbitMQ安装

      2020-02-26

      #MQ

    • ELK日志平台-中

      2020-02-11

      #日志#ELK

    • ELK日志平台-上

      2020-02-10

      #日志#ELK

    • Java8新特性

      2020-02-08

      #Java

    • 1-Hystrix知多少

      2020-01-01

      #面试#Hystrix

    • 25-Nginx变量原理-应用

      2019-12-13

      #Nginx

    • 24-详解HTTP过滤模块

      2019-12-12

      #Nginx

    • 23-详解HTTP请求的11个阶段

      2019-12-11

      #Nginx

    • 22-如何找到处理请求的Server指令块

      2019-12-10

      #Nginx

    • 21-Nginx中的正则表达式

      2019-12-09

      #Nginx

    • 20-处理HTTP请求头部流程

      2019-12-09

      #Nginx

    • 19-Nginx中Listen指令用法

      2019-12-08

      #Nginx

    • 18-Nginx冲突的配置指令以谁为准

      2019-12-08

      #Nginx

    • 17-Nginx动态模块

      2019-12-07

      #Nginx

    • 16-Nginx容器

      2019-12-06

      #Nginx

    • 15-Worker集成协同工作的关键

      2019-12-06

      #Nginx

    • 14-Nginx连接池处理网络请求-内存池对性能的影响

      2019-12-05

      #Nginx

    • 13-Nginx模块

      2019-12-04

      #Nginx

    • 12-网络收发与Nginx事件模型

      2019-12-03

      #Nginx

    • 11-Nginx架构_相关流程

      2019-12-02

      #Nginx

    • LinkedHashMap实现原理_探险

      2019-11-28

      #Java#源码解析

    • HashTable实现原理_探险

      2019-11-22

      #Java#源码解析

    • HashMap实现原理_探险

      2019-11-20

      #Java#源码解析

    • LinkList实现原理_探险

      2019-11-17

      #Java#源码解析

    • ArrayList实现原理_探险

      2019-11-16

      #Java#源码解析

    • 10-OpenResty用Lua语言实现简单服务

      2019-11-12

      #Nginx

    • 9-SSL-Nginx

      2019-11-11

      #Nginx#SSL

    • 8-Nginx配置文件简易解析

      2019-11-10

      #Nginx

    • 7-Nginx安装详解

      2019-11-09

      #Nginx

    • 6-GoAccess实现可视化并实时监控access日志

      2019-11-08

      #Nginx#Tools#日志

    • 5-Nginx搭建具备缓存功能的反向代理

      2019-11-05

      #Nginx

    • 4-Nginx搭建静态资源Web服务器

      2019-11-01

      #Nginx

    • SpringBoot中jar为什么可以直接运行

      2019-10-30

      #面试#SpringBoot

    • SpringBoot全局异常处理

      2019-10-29

      #面试#SpringBoot

    • SpringBoot事件和监听器

      2019-10-29

      #面试#SpringBoot

    • SpringBoot启动原理

      2019-10-29

      #面试#SpringBoot

    • 36-为什么临时表可以重名

      2019-10-28

      #MySql

    • 35-join语句如何优化

      2019-10-27

      #MySql

    • 34-到底可不可以使用join

      2019-10-26

      #MySql

    • 33-我查这么多数据_会不会把数据库内存打爆

      2019-10-24

      #MySql

    • 32-为什么有kill不掉的语句

      2019-10-23

      #MySql

    • 31-误删数据后除了跑路_还能怎么办

      2019-10-22

      #MySql

    • 3-Nginx命令行演示-重载-热部署-切割

      2019-10-20

      #Nginx

    • 2-Nginx配置语法

      2019-10-17

      #Nginx

    • 1-Nginx的前世今生

      2019-10-15

      #Nginx

    • 0-Nginx访问日志配置及信息详解

      2019-10-11

      #Nginx

    • 分布式事务

      2019-09-19

      #面试#系统架构#分布式

    • 分布式锁

      2019-09-18

      #面试#系统架构#分布式

    • 分布式锁与事务

      2019-09-16

      #面试#系统架构#分布式

    • 数据结构与算法第四阶段学习图

      2019-09-16

      #算法

    • 数据结构与算法第三阶段学习图

      2019-09-16

      #算法

    • 数据结构与算法第二阶段学习图

      2019-09-16

      #算法

    • 数据结构与算法第一阶段学习图

      2019-09-16

      #算法

    • 2018-2019工作总结

      2019-09-15

      #搬砖结晶

    • 开发常见问题

      2019-09-14

      #Java

    • 52-算法实战(五)_如何用学过的数据结构和算法实现一个短网址系统

      2019-09-14

      #算法

    • 30-用动态的观点看加锁

      2019-09-13

      #MySql

    • 29-如何判断一个数据库是不是出问题了

      2019-09-12

      #MySql

    • 28-读写分离有哪些坑

      2019-09-11

      #MySql

    • 51-算法实战(四)_剖析微服务接口鉴权限流背后的数据结构和算法

      2019-09-09

      #算法

    • 50-算法实战(三)_剖析高性能队列Disruptor背后的数据结构和算法

      2019-09-06

      #算法

    • 49-算法实战(二)_剖析搜索引擎背后的经典数据结构和算法

      2019-09-02

      #算法

    • 27-主库出问题了_从库怎么办

      2019-08-29

      #MySql

    • 26-备库为什么会延迟好几个小时

      2019-08-28

      #MySql

    • 25-MySQL是怎么保证高可用的

      2019-08-27

      #MySql

    • 24-MySQL是怎么保证主备一致的

      2019-08-26

      #MySql

    • 48-算法实战(一)_剖析Redis常用数据类型对应的数据结构

      2019-08-25

      #算法

    • 47-并行算法_如何利用并行处理提高算法的执行效率

      2019-08-20

      #算法

    • 46-索引_如何在海量数据中快速查找某个数据

      2019-08-16

      #算法

    • 45-搜索_如何用A*搜索算法实现游戏中的寻路功能

      2019-08-13

      #算法

    • 44-B+树_MySQL数据库索引是如何实现的

      2019-08-10

      #算法

    • 43-向量空间_如何实现一个简单的音乐推荐系统

      2019-08-08

      #算法

    • 42-概率统计_如何利用朴素贝叶斯算法过滤垃圾短信

      2019-08-05

      #算法

    • 41-位图_如何实现网页爬虫中的URL去重功能

      2019-08-02

      #算法

    • 40-最短路径_地图软件是如何计算出最优出行路径的

      2019-07-28

      #算法

    • 39-拓扑排序_如何确定代码源文件的编译依赖关系

      2019-07-24

      #算法

    • 38-动态规划实战_如何实现搜索引擎中的拼写纠错功能

      2019-07-20

      #算法

    • 23-MySQL是如何保证数据不丢的

      2019-07-19

      #MySql

    • 22-MySQL有哪些“饮鸩止渴”提高性能的方法

      2019-07-18

      #MySql

    • 21-为什么我只改一行的语句_锁还这么多

      2019-07-17

      #MySql

    • 20-幻读是什么_幻读有什么问题

      2019-07-16

      #MySql

    • 19-只查一行的语句为何执行这么慢

      2019-07-15

      #MySql

    • 37-动态规划理论_一篇文章带你彻底搞懂最优子结结构_无后效性_重复子问题

      2019-07-13

      #算法

    • 36-初识动态规划_如何巧妙解解决“双十一”购物时的凑单问题

      2019-07-09

      #算法

    • 35-回溯算法_从电影《蝴蝶效应》中学习回溯算法的核心思想

      2019-07-06

      #算法

    • 34-分治算法_谈一谈大规模计算框架MapReduce中的分治思想

      2019-07-04

      #算法

    • 33-贪心算法_如何用贪心算法实现Huffman压缩编码

      2019-07-01

      #算法

    • 32-AC自动机_如何用多模式串匹配实现敏感词过滤功能

      2019-06-25

      #算法

    • 18-SQL语句逻辑相同_性能却为何差异巨大

      2019-06-23

      #MySql

    • 17-如何正确的显示随机消息

      2019-06-22

      #MySql

    • 16-MySQL中order by是如何工作的

      2019-06-20

      #MySql

    • 15-日志和索引有关问题

      2019-06-18

      #MySql

    • RocketMQ探索

      2019-06-17

      #MQ

    • 14-count(\*)为什么这么慢

      2019-06-16

      #MySql

    • 13-为什么表数据删掉一半而表文件大小不变

      2019-06-15

      #MySql

    • 12-为什么我的MySQL会“抖”一下

      2019-06-13

      #MySql

    • 11-怎么给字符串字段加索引

      2019-06-12

      #MySql

    • 10-MySQL为什么有时候会选错索引

      2019-06-11

      #MySql

    • 3-3-Docker容器用法

      2019-06-10

      #Docker

    • RabbitMQ详解

      2019-06-08

      #MQ

    • 5-分布式会话_锁_事务_高并发系统设计

      2019-06-07

      #面试

    • 3.2-Docker镜像用法

      2019-06-05

      #Docker

    • 4-Zookeeperer使用场景

      2019-06-04

      #面试

    • Dubbo知多少

      2019-06-03

      #面试#Dubbo

    • 3-分布式系统中接口调用顺序性如何保证

      2019-06-03

      #面试#Dubbo

    • 2-分布式系统中接口的幂等性该如何保证_比如不能重复扣款

      2019-06-02

      #面试#Dubbo

    • 1-分布式系统连环炮_Dubbo有关知识点

      2019-06-01

      #面试#Dubbo

    • 9-普通索引和唯一索引如何选择

      2019-05-30

      #MySql

    • 8-事务到底是隔离的还是不隔离的

      2019-05-29

      #MySql

    • 7-行锁功过_怎么减少行锁对性能的影响

      2019-05-28

      #MySql

    • 6-全局锁和表锁_给表加个字段怎么有这么多阻碍

      2019-05-27

      #MySql

    • 5-深入浅出索引(下)

      2019-05-26

      #MySql

    • 4-深入浅出索引(上)

      2019-05-25

      #MySql

    • 3.1-Docker用法

      2019-05-24

      #Docker

    • 2.2-Docker启动报错

      2019-05-23

      #Docker

    • 3-事务隔离_为什么你改了我还看不见

      2019-05-21

      #MySql

    • MySQL重要日志

      2019-05-20

      #面试#MySql

    • 2-日志系统_一条SQL更新语句是如何执行的

      2019-05-20

      #MySql

    • 1-基础架构_一条SQL查询语句是如何执行的

      2019-05-19

      #MySql

    • 2.1-Docker安装与部署

      2019-05-18

      #Docker

    • 1-Docker缘由

      2019-05-12

      #Docker

    • 0-Docker配置国内免费registry_mirror

      2019-05-08

      #Docker

    • 5-分布式搜索引擎如何部署

      2019-04-26

      #Elasticsearch#面试

    • 4-ES如何在几十亿数据场景下优化查询性能

      2019-04-23

      #Elasticsearch#面试

    • 3-ES读写数据的工作原理

      2019-04-22

      #Elasticsearch#面试

    • 2-分布式搜索引擎的架构是如何设计的

      2019-04-21

      #Elasticsearch#面试

    • 1-面试官对分布式搜索引擎的4个连环炮

      2019-04-20

      #Elasticsearch#面试

    • 8-如何设计一个消息队列

      2019-04-10

      #面试#MQ

    • 7-消息队列如何解决延迟_过期失效_积压消息等问题

      2019-04-10

      #面试#MQ

    • JWT学习

      2019-04-09

      #Java#Jwt

    • 6-消息队列如何保证消息的顺序性

      2019-04-08

      #面试#MQ

    • 5-消息队列如何保证可靠性传输(消息丢了怎么办)

      2019-04-07

      #面试#MQ

    • 4-消息队列消费到重复数据怎么办

      2019-04-06

      #面试#MQ

    • 3-消息队列如何保证高可用性

      2019-04-03

      #面试#MQ

    • 2-消息队列引入原原因_优缺点_应用场景_技术选型

      2019-04-02

      #面试#MQ

    • 1-面试官对消息队列的10个连环炮

      2019-04-01

      #面试#MQ

    • Git常见200+条命令

      2019-03-28

      #Git

    • 8-GitLab简单操作

      2019-03-25

      #Git

    • 31-Trie树_如何实现搜索引擎的搜索关键词提示功能

      2019-03-12

      #算法

    • 7-基于GitHub进行团队协作

      2019-03-09

      #Git

    • 30-字符串匹配基础下_如何借助BM算法轻松理解KMP算法

      2019-03-06

      #算法

    • 29-字符串匹配基础中_如何实现文本编辑器中的查找功能

      2019-03-03

      #算法

    • 28-字符串匹配基础上_如何借助哈希算法实现高效字符串匹配

      2019-03-01

      #算法

    • 6-GitHub的认识与使用

      2019-02-25

      #Git

    • 5-Git集成使用禁忌

      2019-02-15

      #Git

    • 27-深度和广度优先搜索_如何找出社交网络中的三度好友关系

      2019-02-13

      #算法

    • 26-图的表示_如何存储微博微信等社交网络中的好友关系

      2019-02-10

      #算法

    • 国内地图坐标系转换

      2019-02-08

      #地图坐标转换

    • 4-Git多人单分支集成协作时的常见场景

      2019-02-08

      #Git

    • 微服务架构-下篇

      2019-02-06

      #系统架构

    • 微服务架构-中篇

      2019-02-03

      #系统架构

    • 微服务架构-上篇

      2019-02-01

      #系统架构

    • Python数据分析工具

      2019-01-30

      #Python

    • Python高级篇

      2019-01-29

      #Python

    • Python中级篇_下

      2019-01-28

      #Python

    • Python中级篇_上

      2019-01-27

      #Python

    • Python初级篇

      2019-01-26

      #Python

    • Python前世今生

      2019-01-25

      #Python

    • 源码分析-MyBatis数据源与连接池

      2019-01-23

      #MyBatis

    • MyBatis初始化做了什么

      2019-01-21

      #MyBatis

    • 3-Git与GitHub简单同步

      2019-01-20

      #Git

    • 2-Git常用场景

      2019-01-18

      #Git

    • 1-Git安装及简单操作

      2019-01-15

      #Git

    • SpringCloud探索与实战

      2019-01-13

      #SpringCloud

    • MyBatis架构与原理

      2019-01-09

      #MyBatis

    • MyBatis原理概括

      2019-01-08

      #MyBatis

    • MyBatis多数据源配置

      2019-01-07

      #MyBatis

    • JVM(八):Jvm知识点概览

      2019-01-06

      #Jvm

    • JVM(七):Jvm调优-工具

      2019-01-05

      #Tools#Jvm

    • JVM(六):Java服务GC参数调优案例

      2019-01-03

      #Jvm

    • JVM(五):GC分析

      2019-01-02

      #Jvm

    • JVM(四):Jvm调优-命令

      2019-01-01

      #Jvm

    • JVM(三):GC算法_垃圾收集器

      2019-01-01

      #Jvm

    • 25-堆的应用_如何获取Top10最热门的搜索关键词

      2018-12-30

      #算法

    • 24-堆和堆排序_为什么说堆排序没有快速排序快

      2018-12-29

      #算法

    • 23-递归树_如何借助树来求解递归算法的时间复杂度

      2018-12-27

      #算法

    • 22-红黑树下_实现红黑树的技巧

      2018-12-25

      #算法

    • 21-红黑树上_为什么工程中都用红黑树这种二叉树

      2018-12-23

      #算法

    • 应用架构演变过程

      2018-12-20

      #Photo

    • MyBatis常用插件

      2018-12-14

      #MyBatis

    • JVM(二):Jvm内存结构

      2018-12-11

      #Jvm

    • JVM(一):Java类加载机制

      2018-12-10

      #Jvm

    • Map-Reduce学习

      2018-11-20

      #BigData

    • 20-二叉树基础下_有了如此高效的散列表—_为什么还需要二叉树

      2018-11-18

      #算法

    • 19-二叉树基础上_什么样的二叉树适合用数组来存储

      2018-11-16

      #算法

    • 18-哈希算法下_哈希算法在分布式系统中有哪些应用

      2018-11-15

      #算法

    • 17-哈希算法上_如何防止数据库中的用户信息被脱库

      2018-11-13

      #算法

    • Hadoop学习

      2018-11-10

      #BigData

    • 16-散列表下_为什么散列表和链表经常一起使用

      2018-11-09

      #算法

    • 15-散列表中_如何打造一个工业级水平的散列表

      2018-11-09

      #算法

    • 14-散列表上_Word文档中的单词拼写检查功能如何实现

      2018-11-08

      #算法

    • 13-跳表_为什么Redis一定要用跳表来实现有序集合

      2018-11-06

      #算法

    • 12-二分查找下_如何快速定位IP对应的省份地址

      2018-11-04

      #算法

    • 11-二分查找上_如何用最省内存的方式实现快速查找功能

      2018-11-02

      #算法

    • 10-排序优化_如何实现一个通用的高性能的排序函数

      2018-11-01

      #算法

    • 9-线性排序_如何根据年龄给100万用户数据排序

      2018-10-28

      #算法

    • 8-排序下_如何用快排思想在O(n)内查找第K大元素

      2018-10-24

      #算法

    • 7-排序上_为什么插入排序比冒泡排序更受欢迎

      2018-10-22

      #算法

    • 6-递归_如何用三行代码找到最终推荐人

      2018-10-20

      #算法

    • 高性能队列-Disruptor

      2018-10-18

      #MQ#Java

    • 5-队列_队列在线程池等有限资源池中的应用

      2018-10-16

      #算法

    • 4-栈_如何实现浏览器的前进和后退功能

      2018-10-13

      #算法

    • Quartz学习

      2018-10-09

      #Java#定时任务#Quartz

    • 3-链表下_如何轻松写出正确的链表代码

      2018-10-06

      #算法

    • 2-链表上_如何实现LRU缓存淘汰算法

      2018-10-06

      #算法

    • 1-数组_为什么很多编程语言中数组都从0开始编号

      2018-10-02

      #算法

    • 复杂度分析-下部

      2018-09-29

      #算法

    • 复杂度分析-上部

      2018-09-28

      #算法

    • 数据结构与算法概览

      2018-09-26

      #算法

    • 请求与响应

      2018-09-17

      #HTTP

    • TextRank基本了解

      2018-09-01

      #算法

    • (5)Hexo踩坑_主题优化

      2018-08-21

      #Hexo-yilia

    • (4)Hexo撰写文章

      2018-08-19

      #Hexo-yilia

    • (3)Hexo常用命令详解

      2018-08-19

      #Hexo-yilia

    • (2)Hexo配置文件详解

      2018-08-17

      #Hexo-yilia

    • 关于Firewalld二三事

      2018-08-15

      #Linux

    • (1)Hexo博客搭建

      2018-08-11

      #Hexo-yilia

    • 修改Vim_tab为4个空格

      2018-08-06

      #Linux

    • CentOs7防火墙开端口测试

      2018-08-01

      #Linux

    • 10-Redis的并发竞争问题及生产环境集群部署架构

      2018-07-30

      #面试#Redis

    • 9-如何保证缓存与数据库双写时的数据一致性

      2018-07-29

      #面试#Redis

    • 8-如何应对缓存雪崩及穿透问题

      2018-07-28

      #面试#Redis

    • 7-Redis集群模式原理

      2018-07-26

      #面试#Redis

    • Redis所需安装包及各种依赖

      2018-07-25

      #Redis

    • 6-Redis挂掉重启后数据如何进行恢复

      2018-07-24

      #面试#Redis

    • 5-Redis高并发高可用有关问题

      2018-07-21

      #面试#Redis

    • 4-Redis过期策略_手写LRU

      2018-07-19

      #面试#Redis

    • 3-Redis常用数据类型及使用场景

      2018-07-18

      #面试#Redis

    • 2-Redis线程模型_单线程效率高的原因

      2018-07-17

      #面试#Redis

    • 1-项目中缓存如何使用

      2018-07-16

      #面试#Redis

    • AWK三剑客

      2018-07-15

      #Linux

    • Maven插件-assembly插件基本使用

      2018-06-28

      #Java#Maven

    • Maven知多少

      2018-06-27

      #Java#Maven

    • 1-分库分表知多少

      2018-06-25

      #面试#MySql

    • MySQL基本用法

      2018-06-21

      #MySql

    • MySQL安装

      2018-06-20

      #MySql

    • Swagger2学习与集成

      2018-05-20

      #SpringBoot#Swagger2

    • SpringBoot面试

      2018-05-16

      #面试#SpringBoot

    • SpringBoot+Docker简单配置

      2018-05-15

      #Docker#SpringBoot

    • Java定时任务

      2018-05-13

      #Java#定时任务

    • Netty知多少

      2018-05-05

      #网络编程

    • Java编程瞎侃

      2018-04-18

      #Java

    • Vim常用操作

      2018-03-25

      #Linux

    • Linux定时任务Crontab详解

      2018-03-23

      #Linux

    • Linux常用插件及乱码

      2018-03-20

      #Linux

    • Linux安装常用软件

      2018-03-19

      #Linux

    • Idea常用插件及个性化配置

      2018-03-18

      #Tools#IDEA

    • Host-Vm相互ping不同到的解决办法

      2018-03-16

      #Linux

    • GitHub
    • 廖雪峰
    • 纯洁的微笑
    • 我没有三颗心脏
    • 阿里巴巴开源镜像网站
    一个脱离了高级趣味的人!