{"id":17920779,"url":"https://github.com/hengyunabc/redis-id-generator","last_synced_at":"2025-04-05T17:06:58.008Z","repository":{"id":28627173,"uuid":"32145955","full_name":"hengyunabc/redis-id-generator","owner":"hengyunabc","description":"distributed id generator based on redis.","archived":false,"fork":false,"pushed_at":"2017-04-18T09:50:42.000Z","size":15,"stargazers_count":465,"open_issues_count":3,"forks_count":205,"subscribers_count":50,"default_branch":"master","last_synced_at":"2025-03-29T16:07:16.312Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hengyunabc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-13T09:01:56.000Z","updated_at":"2025-01-10T00:43:02.000Z","dependencies_parsed_at":"2022-08-21T21:50:48.815Z","dependency_job_id":null,"html_url":"https://github.com/hengyunabc/redis-id-generator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hengyunabc%2Fredis-id-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hengyunabc%2Fredis-id-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hengyunabc%2Fredis-id-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hengyunabc%2Fredis-id-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hengyunabc","download_url":"https://codeload.github.com/hengyunabc/redis-id-generator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-28T20:27:15.507Z","updated_at":"2025-04-05T17:06:57.984Z","avatar_url":"https://github.com/hengyunabc.png","language":"Java","funding_links":[],"categories":["Java","分布式开发"],"sub_categories":[],"readme":"# redis-id-generator\ndistributed id generator based on redis.\n\n基于redis的分布式ID生成器。\n## 准备\n\n首先，要知道redis的EVAL，EVALSHA命令：\n\nhttp://redis.io/commands/eval\n\nhttp://redis.io/commands/evalsha\n\n## 原理\n利用redis的lua脚本执行功能，在每个节点上通过lua脚本生成唯一ID。\n生成的ID是64位的：\n\n* 使用41 bit来存放时间，精确到毫秒，可以使用41年。  \n* 使用12 bit来存放逻辑分片ID，最大分片ID是4095\n* 使用10 bit来存放自增长ID，意味着每个节点，每毫秒最多可以生成1024个ID  \n\n比如GTM时间 ```Fri Mar 13 10:00:00 CST 2015``` ，它的距1970年的毫秒数是 ```1426212000000```，假定分片ID是53，自增长序列是4，则生成的ID是：\n```\n5981966696448054276 = 1426212000000 \u003c\u003c 22 + 53 \u003c\u003c 10 + 4\n```\n\nredis提供了[TIME](http://redis.io/commands/time)命令，可以取得redis服务器上的秒数和微秒数。因些lua脚本返回的是一个四元组。\n```\nsecond, microSecond, partition, seq\n```\n\n客户端要自己处理，生成最终ID。\n```\n((second * 1000 + microSecond / 1000) \u003c\u003c (12 + 10)) + (shardId \u003c\u003c 10) + seq;\n```\n\n### 集群实现原理\n假定集群里有3个节点，则节点1返回的seq是：\n```\n0, 3, 6, 9, 12 ...\n```\n节点2返回的seq是\n```\n1, 4, 7, 10, 13 ...\n```\n节点3返回的seq是\n```\n2, 5, 8, 11, 14 ...\n```\n这样每个节点返回的数据都是唯一的。\n\n### 注意事项\n\n* 要求redis server版本是3.2以上，因为使用到了`redis.replicate_commands()`\n\n参考：http://redis.io/commands/eval\n\n* 因为是利用了redis的time命令来获取到redis服务器上的时间，所以reids服务器的时间要保证是只增长的，要关闭服务器上的ntp等时间同步机制。\n\n## 单个节点部署\n\n下载redis-script-node1.lua，并把它load到redis上。\n```bash\ncd redis-directory/\nwget https://raw.githubusercontent.com/hengyunabc/redis-id-generator/master/redis-script-node1.lua\n./redis-cli script load \"$(cat redis-script-node1.lua)\"\n```\n获取lua脚本的sha1值，可能是：\n```\nc5809078fa6d652e0b0232d552a9d06d37fe819c\n```\n在代码里，通过EVALSHA命令，传递这个sha1值，就可以得到生成的ID。\n\n比如，通过命令行执行：\n```bash\n./redis-cli EVALSHA c5809078fa6d652e0b0232d552a9d06d37fe819c 2 test 123456789\n```\n结果可能是：\n```\n1) (integer) 1426238286\n2) (integer) 130532\n3) (integer) 277\n4) (integer) 4\n```\n\n## 集群部署\n假定集群是3个节点，则分别对三个节点执行：\n```bash\n./redis-cli -host node1 -p 6379 script load \"$(cat redis-script-node1.lua)\"\n./redis-cli -host node2 -p 7379 script load \"$(cat redis-script-node2.lua)\"\n./redis-cli -host node3 -p 8379 script load \"$(cat redis-script-node3.lua)\"\n```\n\n## 性能\nredis默认配置。\n\n```\n单节点，单线程：\ntime:0:00:00.959\nspeed:10427.52867570386\n单节点，20线程：\ntime:0:00:06.710\nspeed:29806.259314456034\n```\n结论：\n- 单节点，qps约3w\n- 可以线性扩展，3个结点足以满足绝大部分的应用\n\n## java客户端封装\n在redis-id-generator-java目录下，有example和benchmark代码。\n\n在调用时，要传入两个参数\n- tag，即为哪一类服务生成ID\n- shardId，即分片由哪个ID生成，比如一个用户的订单，则分片ID应该由userId来生成\n\n```java\npublic class Example {\n\n\tpublic static void main(String[] args) {\n\t\tString tab = \"order\";\n\t\tlong userId = 123456789;\n\n\t\tIdGenerator idGenerator = IdGenerator.builder()\n\t\t\t\t.addHost(\"127.0.0.1\", 6379, \"c5809078fa6d652e0b0232d552a9d06d37fe819c\")\n//\t\t\t\t.addHost(\"127.0.0.1\", 7379, \"accb7a987d4fb0fd85c57dc5a609529f80ec3722\")\n//\t\t\t\t.addHost(\"127.0.0.1\", 8379, \"f55f781ca4a00a133728488e15a554c070b17255\")\n\t\t\t\t.build();\n\n\t\tlong id = idGenerator.next(tab, userId);\n\n\t\tSystem.out.println(\"id:\" + id);\n\t\tList\u003cLong\u003e result = IdGenerator.parseId(id);\n\n\t\tSystem.out.println(\"miliSeconds:\" + result.get(0) + \", partition:\"\n\t\t\t\t+ result.get(1) + \", seq:\" + result.get(2));\n\t}\n}\n```\n\n## 多语言客户端\n只要支持redis evalsha命令就可以了。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhengyunabc%2Fredis-id-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhengyunabc%2Fredis-id-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhengyunabc%2Fredis-id-generator/lists"}