zoukankan      html  css  js  c++  java
  • 高性能高可用的分布式唯一ID服务——mooon-uniq-id

    目录

    目录 1

    1. 前言 1

    2. 名词 1

    3. 功能 1

    4. 唯一性原理 2

    5. 系统结构 2

    5.1. mooon-uniq-agent 2

    5.2. mooon-uniq-master 2

    6. 限制 3

    7. 核心思想 4

    8. 编译&安装 4

    9. 启动&运行 5

    10. 编程使用 5

    1. 前言

    源码位置:https://github.com/eyjian/mooon/tree/master/application/uniq_id

    mooon-uniq-id可单机运行,也可以由1~255台机器组成集群分布式运行。性能极高,单机批量取(每批限定最多100个),每秒可提供2000个唯一ID服务,单个取每秒可以提供20唯一ID服务。

    mooon-uniq-id还具极高的可用性,只要有一台机器正常即可正常提供服务。

    2. 名词

    Lable 机器标签

    3. 功能

    mooon-uniq-id提供64位无符号整数唯一ID和类似于订单号、流水号的字符串唯一ID

    4. 唯一性原理

    mooon-uniq-id生成的唯一ID通过以下公式保证:

    唯一ID = 机器唯一标签 本机递增序列号 系统时间

    机器唯一标签自动生成,取值从1~255,故最多支持255台机器组成集群。时间粒度为小时,单台机器一小时内的递增序列号值为536870911个,只要一小时内提供的唯一ID数不超过536870911个即是安全的。如果需求超过536870911,则可以扩展到分钟的粒度,mooon-uniq-id保留了6位供用户自由支配,这保留的6位可以用于存储分钟值。

    5. 系统结构

    mooon-uniq-id的实现为单进程无线程UDP实现简单高效。采用弱主架构,这种架构下,master在一段时间内不可用,完全不影响正常服务。租期为多长,即可允许多长时间内master不可用,比如租期为7天,则7天内master不可用都不影响正常服务,agentmaster的依赖非常低,因此叫弱主架构。

    mooon-uniq-idmooon-uniq-agentmooon-uniq-master组成弱主架构,为保证可用性mooon-uniq-agent至少1台以上,而且只要有一台可以用即整体可用。

    mooon-uniq-master一般可部署2台形成主备,实际上部署一台也完全无问题,因为mooon-uniq-master只要在租期内恢复正常即可。

    5.1. mooon-uniq-agent

    对外提供获取唯一ID服务的是mooon-uniq-agent,至少应当部署2台,以提供必要的可用性,部署的越多可用性越高,同时每秒提供的唯一ID个数也越多,支撑的并发数也越大。

    mooon-uniq-agent在能够对外服务之前,都必须先从mooon-uniq-master租约到机器标签,否则不能服务。

    5.2. mooon-uniq-master

    mooon-uniq-master负责租约的管理,包括租约的初始化、租约的分配和租约的过期管理和回收。

    默认情况下,mooon-uniq-agent每隔1分钟以心跳的形式向mooon-uniq-master续租机器标签,可以通过命令行参数“--interval”修改续租间隔,参数值的单位为秒,默认值为6001分钟。

    mooon-uniq-master将机器标签存储在MySQL表中,各机器标签的状态也存储在MySQL表中。mooon-uniq-masterMySQL有依赖,但也不是强依赖,因为只要在租期内可以成功续租或新租成功即可,而一旦集群上线后,99.999%的时间都只是续租。

    在启动mooon-uniq-master之前,需要先创建好如下3MySQL库和表:

    -- CREATE DATABASE IF NOT EXISTS uniq_id DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

    -- Label资源池表

    -- mooon-uniq-master第一次启动时会初始化表t_label_pool

    DROP TABLE IF EXISTS t_label_pool;

    CREATE TABLE t_label_pool (

        f_label TINYINT UNSIGNED NOT NULL,

        PRIMARY KEY (f_label)

    );

    -- Label在线表

    -- f_label为主键,保证同一时间不可能有两个IP租赁同一个Label,

    -- 但一个IP可能同时持有一个或多个过期的Label,和一个当前有效的Label

    DROP TABLE IF EXISTS t_label_online;

    CREATE TABLE t_label_online (

        f_label TINYINT UNSIGNED NOT NULL,

        f_ip CHAR(16) NOT NULL,

        f_time DATETIME NOT NULL,

        PRIMARY KEY (f_label),

        KEY idx_ip(f_ip),

        KEY idx_time(f_time)

    );

    -- Label日志表

    -- 记录租约和续租情况

    DROP TABLE IF EXISTS t_label_log;

    CREATE TABLE t_label_log (

        f_id BIGINT NOT NULL AUTO_INCREMENT,

        f_label TINYINT UNSIGNED NOT NULL,

        f_ip CHAR(16) NOT NULL,

        f_event TINYINT NOT NULL,

        f_time DATETIME NOT NULL,

        PRIMARY KEY (f_id),

        KEY idx_label(f_label),

        KEY idx_ip(f_ip),

        KEY idx_event(f_event),

        KEY idx_time(f_time)

    );

    6. 限制

    ID具备唯一性,但不具备递增性。

    7. 核心思想

    要保证ID的唯一性,最关键是要保证同一个机器标签不能同时出现在多台机器上。mooon-uniq-id的实现引入租约,每台mooon-uniq-agent在服务之前需要先成功租约到机器标签,在租约期内独占标签,并且可以在租期内续租。

    在租期后,每个机器标签还有一段冻结期,处于冻结期的机器标签不会被租约。

    通过这样的一种机制保证了机器标签的安全性,只要每台mooon-uniq-agent保证序列号在该机器上唯一,那么两者相结合即保证了整体上的唯一性。

    序列号总是有限的,为保证永久的唯一性,在组成唯一ID时,加上了时间共同组成唯一性。

    8. 编译&安装

    mooon-uniq-id依赖mooon基础库,使用gitTortoiseGit下载mooon库源码:

    https://github.com/eyjian/mooon/tree/master/mooon

    同样,使用gitTortoiseGit下载mooon-uniq-id源码:

    https://github.com/eyjian/mooon/tree/master/application/uniq_id

    两者均采用CMake编译,且编译方法相同,先编译mooon基础库,编译和安装步骤:

    1) 进入源代码目录,执行cmake生成Makefile文件,安装目录指定为/usr/local/mooon:

    cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr/local/mooon .

    2) 执行make编译源代码:

    make

    3) 在make成功后,执行“make install”完成安装:

    /usr/local/mooon

    ├── bin

    ├── CMake.common

    ├── include

    │     └── mooon

    │           ├── net

    │           ├── sys

    │           └── utils

    └── lib

           └── libmooon.a

    接着编译和安装mooon-uniq-id,方法相同,安装路径也请指定为/usr/local/mooon。

    9. 启动&运行

    简单点可以放到crontab中自动拉起,比如借助process_monitor.sh(下载:https://github.com/eyjian/mooon/blob/master/mooon/shell/process_monitor.sh)的监控和自动重启功能:

    * * * * * /usr/local/bin/process_monitor.sh "/usr/local/uniq_id/bin/uniq_master" "/usr/local/uniq_id/bin/uniq_master --db_host=127.0.0.1 --db_port=3306 --db_user=zhangsan --db_pass='zS2018' --db_name=uniq_id"

    * * * * * /usr/local/bin/process_monitor.sh "/usr/local/uniq_id/bin/uniq_agent" "/usr/local/uniq_id/bin/uniq_agent --master_nodes=192.168.31.33.225.168.251:16200,192.168.31.35:16200"

    10. 编程使用

    可以参考uniq_test.cppuniq_stress.cpp使用mooon-uniq-id,如:

    bool polling = false; // 轮询还是随机选择mooon-uniq-agent

    const uint32_t timeout_milliseconds = 200;

    const uint8_t retry_times = 5;

    // 注意:需要捕获CSyscallException和CException两种异常

    try

    {

        // agent_nodes为mooon-uniq-agent连接信息,多个间以逗号分隔,注意不要包含空格:

        // 如:192.168.1.31:6200,192.168.1.32:6200,192.168.1.33:6200

        mooon::CUniqId uniq_id(agent_nodes, timeout_milliseconds, retry_times, polling);

        // 取交易流水号

        //

        // %L 为取mooon-uniq-agent的机器标签,每个mooon-uniq-agent不会有相同的标签

        // %Y 为YYYY格式的年,如2017

        // %M 为MM格式的月,如:04或12等

        // %D 为DD格式的日,如:01或31等

        // %m 为mm格式的分钟,如:09或59等

        // %H 为hh格式的小时,24小时制,如:03或23等

        // %5S 表示取5位的序列号,不足时前补0

        std::string transaction_id = uniq_id.get_transaction_id("%L%Y%M%D%m%5S");

        fprintf(stdout, "%s ", transaction_id.c_str());

        // 取8字节无符号整数值

        const uint64_t uniq_id = uniq_id.get_uniq_id();

        union mooon::UniqID uid;

        uid.value = uniq_id;

        fprintf(stdout, "id: %" PRIu64" => %s ", uniq_id, uid.id.str().c_str());

    }

    catch (mooon::sys::CSyscallException& ex)

    {

        fprintf(stderr, "%s ", ex.str().c_str());

    }

    catch (mooon::utils::CException& ex)

    {

        fprintf(stderr, "%s ", ex.str().c_str());

    }

  • 相关阅读:
    How To Build CyanogenMod Android for smartphone
    CentOS安装Code::Blocks
    How to Dual boot Multiple ROMs on Your Android SmartPhone (Upto Five Roms)?
    Audacious——Linux音乐播放器
    How to Dual Boot Multiple ROMs on Your Android Phone
    Everything You Need to Know About Rooting Your Android Phone
    How to Flash a ROM to Your Android Phone
    什么是NANDroid,如何加载NANDroid备份?
    Have you considered compiled a batman-adv.ko for android?
    BATMAN—Better Approach To Mobile Adhoc Networking (B.A.T.M.A.N.)
  • 原文地址:https://www.cnblogs.com/aquester/p/9891506.html
Copyright © 2011-2022 走看看