{"id":18385669,"url":"https://github.com/yiding-he/hydrogen-ssdb","last_synced_at":"2025-08-17T10:35:17.341Z","repository":{"id":57724296,"uuid":"47387943","full_name":"yiding-he/hydrogen-ssdb","owner":"yiding-he","description":"Java 编写的 SSDB 客户端，支持负载均衡","archived":false,"fork":false,"pushed_at":"2024-10-03T18:50:51.000Z","size":1354,"stargazers_count":54,"open_issues_count":2,"forks_count":21,"subscribers_count":7,"default_branch":"1.2.8","last_synced_at":"2025-07-07T07:04:27.285Z","etag":null,"topics":["java","ssdb","ssdb-client"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yiding-he.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-04T07:14:13.000Z","updated_at":"2025-06-30T06:16:32.000Z","dependencies_parsed_at":"2025-01-23T03:11:37.680Z","dependency_job_id":"3de0d5d3-7d75-42a5-883b-60824dc39e30","html_url":"https://github.com/yiding-he/hydrogen-ssdb","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/yiding-he/hydrogen-ssdb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiding-he%2Fhydrogen-ssdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiding-he%2Fhydrogen-ssdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiding-he%2Fhydrogen-ssdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiding-he%2Fhydrogen-ssdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yiding-he","download_url":"https://codeload.github.com/yiding-he/hydrogen-ssdb/tar.gz/refs/heads/1.2.8","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiding-he%2Fhydrogen-ssdb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270837404,"owners_count":24654375,"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","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["java","ssdb","ssdb-client"],"created_at":"2024-11-06T01:18:36.580Z","updated_at":"2025-08-17T10:35:17.310Z","avatar_url":"https://github.com/yiding-he.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hydrogen-ssdb\nJava 编写的 SSDB 客户端。\n\n## 交流\n\n为了更快速的解决 issue，所以建立了一个 QQ 群。\n\n![hydrogen-ssdb群二维码](https://user-images.githubusercontent.com/900606/88889218-5efd8880-d272-11ea-9691-1f5bd80a4fc6.png)\n\n```\n群名称：hydrogen-ssdb\n群号：1148460774\n```\n\n## 介绍\n\nhydrogen-ssdb 是一个 Java 编写的 [SSDB](https://github.com/ideawu/ssdb)  客户端，支持多线程并发请求和多服务器的负载均衡（客户端分发请求）。\n\nSSDB 是一个类似 Redis 的 NOSQL 数据库，兼容 Redis 的数据结构和部分命令，且支持多线程，内存占用小。\n\nhydrogen-ssdb 是一个 SSDB 客户端，具有以下特性：\n\n1. 易于配置，易于使用；\n1. 支持 SSDB 主从集群与负载均衡；\n1. 当集群中的服务器 down 掉时，能自动识别并跳过该服务器。\n\n#### 【负载均衡的抽象和实现】\n\nhydrogen-ssdb 将负载均衡抽象为`Sharding`类，该类负责决定一个请求应该发送给哪台 SSDB 服务器。\n\n在`Sharding`中，所有的服务器（`Server`）被归为多个集群（`Cluster`），`Cluster` 是负载均衡的顶层单位。每个 `Cluster` 包含多个 `Server`，一个 `Server` 可以是主服务器，也可以是从服务器（这个必须与 SSDB 实际的主从配置严格一致），但 `Cluster` 中必须要有主服务器。\n\nhydrogen-ssdb 缺省实现了基于一致性哈希环的负载均衡方式。如果这种方式不适合您的实际情况，您可以自己实现`Sharding`的子类，然后通过`SsdbClient`的构造方法传入。下面是一个如何使用自定义`Sharding`的例子，假设你已经实现了自定义的`MySharding`类：\n\n```java\nMySharding mySharding = ...  // 自定义 Sharding\nSsdbClient client = new SsdbClient(mySharding);\n```\n\n下面介绍 hydrogen-ssdb 缺省实现的负载均衡的原理。\n\n#### 【基于一致性哈希环的负载均衡】\n\n![](https://cloud.githubusercontent.com/assets/900606/11584478/2c30724c-9a9f-11e5-8fa2-3917230a227b.png)\n\n#### 【对某些命令的处理】\n\n在多服务器环境下，某些命令会发送给所有的 cluster，然后收集结果，例如 `scan()` 方法；\n\n还有些命令仅仅在单服务器下执行，例如 `multiGet()` 方法，当在多服务器下时，它不会执行 `multi_get` 命令，而是对每个 key 依次调用 get 方法，然后收集结果。\n\n#### 【对单点故障的处理】\n\n在负载均衡当中，每个节点都负责整个一致性哈希环中的一部分（称为哈希段）。当负载均衡当中出现单点故障时，故障节点对应的哈希段将无法执行存取操作，于是有两种处理方式：\n\n1. 故障节点前面的节点自动接管该哈希段。这种方式适用于将 SSDB 用于缓存，因为缓存丢失是可以重新填充的；\n2. 保留哈希段的故障状态，直到故障节点恢复。这种方式适用于将 SSDB 用于数据库，这样能严格保证一个 key 会保存在对应的节点中。\n\nhydrogen-ssdb 缺省情况下使用第一种方式来处理。如果需要修改，可以以下面的方式：\n\n```java\nConsistentHashSharding sharding = (ConsistentHashSharding)ssdbClient.getSharding();\nsharding.setSpofStrategy(SPOFStrategy.PreserveKeySpaceStrategy);\n```\n\n#### 【如何添加 Cluster】\n\n对于一致性哈希环，每一个 Cluster 的哈希段都是固定的，所以每添加一个新的 Cluster，都只会给当前的其中 1 个 Cluster 减负，而不是给所有的 Cluster 减负。例如当前有 A、B、C 三个 Cluster，那么当添加一个 D 到 A 和 B 之间，形成 “A-D-B-C” 时，它只会分担 A 的一部分哈希段，B 和 C 的哈希段没有改变，也就是说 B 和 C 的负载没有变化。\n\n`ConsistentHashSharding` 使用 key 的 MD5 签名的前四个字节作为 hash 值，以尽可能让所有的 key 均匀分布。\n\n由此可知，在添加 Cluster 之前，你需要明确的了解每个 Cluster 当前的负载情况，找到负载最重的 Cluster，将新的 Cluster 加在它后面。\n\n所以，`ConsistentHashSharding` 的 `addCluster()` 方法有两个参数，第一个是要添加的 Cluster，第二个是需要被分担负载的 Cluster。\n\n新加入的 Cluster 和原有的 Cluster 将根据双方的权重值重新分配原来的哈希段。假设两个 Cluster 的权重相同，则平分原来的哈希段。这个过程和其他的 Cluster 权重无关。\n\n## 项目依赖\n\nhydrogen-ssdb 依赖于下面两个框架：\n\n* Apache commons-pool2 （对象池框架）\n* slf4j （日志框架）\n\n## 使用方法\n\n#### 依赖关系\n\n在 `\u003cdependencies\u003e` 元素当中添加下面的内容：\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.yiding-he\u003c/groupId\u003e\n  \u003cartifactId\u003ehydrogen-ssdb\u003c/artifactId\u003e\n  \u003cversion\u003e${hydrogen-ssdb.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### 基本使用方法\n\n```java\nSsdbClient client = new SsdbClient(host, port);\nclient.set(\"key\", \"value\");\nSystem.out.println(client.get(\"key\"));   // output \"value\"\nclient.close();    // 应用结束时需要调用 close() 方法，也可以配置在 Spring 的 destroy-method 中\n```\n\n#### 配置主从服务器\n```java\nList\u003cServer\u003e servers = Arrays.asList(\n        new Server(\"192.168.1.180\", 8888, true),  // 主服务器\n        new Server(\"192.168.1.180\", 8889, false)  // 从服务器\n);\n\nSsdbClient client = SsdbClient.fromSingleCluster(servers);\nclient.set(\"name\", \"hydrogen-ssdb\");    // 写入请求一定会发送给主服务器\nSystem.out.println(client.get(\"name\")); // 读取请求会随机发送给任意一台服务器\n```\n\n#### 配置负载均衡\n\n```java\nSharding sharding = new ConsistentHashSharding(Arrays.asList(\n        new Cluster(new Server(\"192.168.1.180\", 8888), 100),  // 100 和 200 这两个参数指的是权重，\n        new Cluster(new Server(\"192.168.1.180\", 8889), 200)   // 权重越大的 Cluster 所保存的 key 越多。\n));\n\nSsdbClient ssdbClient = new SsdbClient(sharding);\n\n```\n\n### 使用注意\n\n#### 线程安全\n\n`SsdbClient` 对象包含了对整个负载均衡的拓扑结构的处理，所以对于每一个由多个 SSDB 服务器组成的负载均衡架构，只需创建一个 `SsdbClient` 对象即可。另外 `SsdbClient` 是线程安全的，所以可以让任意多个线程访问。\n\n#### 误用导致内存占用过高\n\n因为一个 `SsdbClient` 对象可能包含一个或多个连接池（每个连接池对应一个 SSDB 服务器），因此请不要创建大量的 `SsdbClient` 对象，这样完全没有必要，也会使得内存很容易被用光。\n\n## 更新\n* 2021-06-29: 版本号更新到 `V1.2.8`\n    * `qpushFront()` 和 `qpushBack()` 方法现在可以接受二维 byte 数组，以便一次保存多组二进制数据。\n* 2021-06-09：版本号更新到 `V1.2.7`\n    * 没有调整执行逻辑，调整连接池创建机制，允许自定义连接池和连接池工厂\n* 2020-10-29: 版本号更新到 `V1.2.6`\n    * SsdbClient 新增 `qpopFrontBytes()`, `qpopBackBytes()`, `qpopAllFrontBytes()`, `qpopAllBackBytes()`, `qfrontBytes()`, `qbackBytes()`, `qrangeBytes()`, `qsliceBytes()`\n* 2020-09-26: 版本号更新到 `V1.2.5`\n    * 修复 `hmultiget` 命令没有正确处理二进制内容的问题\n* 2020-07-10: 版本号更新到 `V1.2.3` \n    * `SsdbClient` 添加 `zexists()` 方法。\n* 2020-01-06: 版本号更新到 `V1.2.2` \n    * `SsdbClient` 添加 `multiGetBytes()` 方法；\n    * `multiSet(List\u003cKeyValue\u003e)` 也支持字节串；\n    * 修复构造方法中超时时间单位错误的问题。\n* 2019-12-31: 版本号更新到 `V1.2.1` KeyValue 的内容类型改为 byte[] 以便处理 SSDB 中的二进制内容。\n* 2019-10-01: 版本 `V1.2.0` 正式发布到 Maven 中心库。\n* 2019-08-06: 版本号更新到 `V1.2.0` 修复了没有 auth 认证的问题\n* 2019-03-27: 版本号更新到 `V1.1.2` 修复了运行过程中添加第二个 Cluster 失败的问题，以及自动扩展哈希段的问题\n* 2019-02-06: 版本号更新到 `V1.1.1` 修复了 `multiGet()` 方法在多服务器环境下返回错误结果的问题。\n* 2018-05-06: 修复了从节点恢复时没有被认作是从节点的问题。\n* 2018-02-25: 版本号更新到 `V1.1.0`，添加了 `multiGet()` 方法，修复了若干方法在多服务器负载均衡上的 BUG。\n* 2017-08-03: 修复了 Cluster 无法恢复的问题，版本号更新到 1.0.1。\n* 2017-06-13: 完成了最后一个基本特性的实现，版本号正式改为 1.0.0。\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyiding-he%2Fhydrogen-ssdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyiding-he%2Fhydrogen-ssdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyiding-he%2Fhydrogen-ssdb/lists"}