浅度渣文

一个简单却是实用的分布式ID解决方案light-id

2019-08-01  本文已影响0人  我是杨正

https://github.com/dubby1994/light-id

动机

希望可以有一个容易部署,容易维护,原理简单(意味着不容易出问题),且性能还不错的分布式ID解决方案,没错,是方案,而不是方法。

ID组成

sign sequence work id
1 bit 53 bit 10 bit

架构图

架构图

底层可以使用MySQL或者Redis,client端需要一个配置文件,如:

{
  "type": "Redis",
  "providers": [
    {
      "id": 1,
      "url": "redis://127.0.0.1:6379/0",
      "namespace": "id_1"
    },
    {
      "id": 2,
      "url": "redis://127.0.0.1:6379/0",
      "namespace": "id_2"
    },
    {
      "id": 3,
      "url": "redis://127.0.0.1:6379/0",
      "namespace": "id_3"
    }
  ],
  "bufferSize": 1000,
  "idleSize": 10,
  "timeout": 10,
  "checkInterval": 10
}
{
  "type": "MySQL",
  "providers": [
    {
      "id": 1,
      "url": "jdbc:mysql://localhost:3306/light_id?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&connectTimeout=60000&socketTimeout=100",
      "namespace": "id_1",
      "options": {
        "username": "root",
        "password": "123456"
      }
    },
    {
      "id": 2,
      "url": "jdbc:mysql://localhost:3306/light_id?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&connectTimeout=60000&socketTimeout=100",
      "namespace": "id_2",
      "options": {
        "username": "root",
        "password": "123456"
      }
    },
    {
      "id": 3,
      "url": "jdbc:mysql://localhost:3306/light_id?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&connectTimeout=60000&socketTimeout=100",
      "namespace": "id_3",
      "options": {
        "username": "root",
        "password": "123456"
      }
    }
  ],
  "bufferSize": 100,
  "idleSize": 10,
  "timeout": 50,
  "checkInterval": 5
}

其中,namespace在MySQL中代表表名,表结构只需要有一个id字段,类型是BIGINT,自增主键就可以了;在Redis中代表key名。

client本地维护了一个buffer,他会轮训各个数据源(MySQL/Redis)来获得一个自增数字num,举例:id=1的redis incr返回x,那么最后的到唯一UNIQUE_ID计算公式为:

UNIQUE_ID = x << 10 | id

使用

MySQL

ConfigFactory configFactory = new ConfigFactory();
GeneratorConfig generatorConfig = configFactory.getGeneratorConfig();
LightIDGenerator lightGenerator = new MySQLGenerator(generatorConfig);
long id = lightGenerator.nextID();

Redis

ConfigFactory configFactory = new ConfigFactory();
GeneratorConfig generatorConfig = configFactory.getGeneratorConfig();
LightIDGenerator lightGenerator = new RedisGenerator(generatorConfig);
long id = lightGenerator.nextID();

其中,默认会读取classpath下light.json文件作为配置文件,可以自己传入一个json格式的配置来初始化ConfigFactory

 BufferedReader reader = new BufferedReader(new InputStreamReader(ConfigFactory.class.getClassLoader().getResourceAsStream("light_redis.json")));
 String json = reader.lines().reduce((a, b) -> a + b).orElseThrow(() -> new IllegalStateException("load config error"));
 reader.close();
 ConfigFactory configFactory = new ConfigFactory(json);

建议

https://github.com/dubby1994/light-id

上一篇下一篇

猜你喜欢

热点阅读