{"id":44610424,"url":"https://github.com/tair-opensource/TairHash","last_synced_at":"2026-02-26T22:01:20.102Z","repository":{"id":37321692,"uuid":"342108499","full_name":"tair-opensource/TairHash","owner":"tair-opensource","description":"A redis module, similar to redis hash, but you can set expiration and version for field.","archived":false,"fork":false,"pushed_at":"2026-01-26T06:44:38.000Z","size":1608,"stargazers_count":249,"open_issues_count":16,"forks_count":44,"subscribers_count":8,"default_branch":"develop","last_synced_at":"2026-01-26T20:49:00.631Z","etag":null,"topics":["expiration","hash","module","redis","version"],"latest_commit_sha":null,"homepage":"","language":"C","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/tair-opensource.png","metadata":{"files":{"readme":"README-CN.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":"2021-02-25T03:16:10.000Z","updated_at":"2026-01-26T06:44:43.000Z","dependencies_parsed_at":"2024-11-09T05:28:51.533Z","dependency_job_id":"348ce317-791d-44d2-8652-e86c9d08b3bf","html_url":"https://github.com/tair-opensource/TairHash","commit_stats":null,"previous_names":["alibaba/tairhash"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/tair-opensource/TairHash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tair-opensource%2FTairHash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tair-opensource%2FTairHash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tair-opensource%2FTairHash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tair-opensource%2FTairHash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tair-opensource","download_url":"https://codeload.github.com/tair-opensource/TairHash/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tair-opensource%2FTairHash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29874453,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T21:05:00.265Z","status":"ssl_error","status_checked_at":"2026-02-26T20:57:13.669Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["expiration","hash","module","redis","version"],"created_at":"2026-02-14T12:00:22.735Z","updated_at":"2026-02-26T22:01:20.094Z","avatar_url":"https://github.com/tair-opensource.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"![](https://img.shields.io/badge/license-Apache--2.0-green)\n![](https://img.shields.io/badge/PRs-welcome-green)\n[![Build](https://github.com/alibaba/TairHash/actions/workflows/cmake.yml/badge.svg)](https://github.com/alibaba/TairHash/actions/workflows/cmake.yml)\n[![CI](https://github.com/alibaba/TairHash/actions/workflows/ci.yml/badge.svg)](https://github.com/alibaba/TairHash/actions/workflows/ci.yml)\n[![Docker](https://github.com/alibaba/TairHash/actions/workflows/docker-image.yml/badge.svg)](https://github.com/alibaba/TairHash/actions/workflows/docker-image.yml)\n[![codecov](https://codecov.io/gh/chenyang8094/TairHash/branch/develop/graph/badge.svg?token=9A8QP7MTN3)](https://codecov.io/gh/chenyang8094/TairHash)  \n\n\n\u003cdiv align=center\u003e\n\u003cimg src=\"imgs/tairhash_logo.jpg\" width=\"500\"/\u003e\n\u003c/div\u003e\n\n## 简介  [英文说明](README.md)\n     TairHash是基于redis module开发的一种hash数据结构，和redis原生的hash数据结构相比，TairHash不但和原生hash一样具有丰富的数据接口和高性能，还可以为field设置过期时间和版本，这极大的提高了hash数据结构的灵活性，在很多场景下可以大大的简化业务开发。TairHash提供active expire机制，即使field在过期后没有被访问也可以被主动删除，释放内存。\n\n\n### 主要的特性如下：\n\n- 支持redis hash的所有命令语义\n- field支持单独设置expire和version\n- 针对field支持高效的active expire和passivity expire，其中active expire支持SCAN_MODE、SORT_MODE和SLAB_MODE模式。\n- 支持field过期删除事件通知（基于pubsub）\n\n## 主动过期\n\n### SCAN_MODE（扫描模式）：\n- 不对TairHash进行全局排序（可以节省内存）\n- 每个TairHash内部依然会使用一个排序索引对fields进行排序（加速每个key内部的field查找）\n- 内置定时器会周期使用SCAN命令找到包含过期field的TairHash，然后检查TairHash内部的排序索引，进行field的淘汰\n- 排序中所有的key和field都是指针引用，无内存拷贝，无内存膨胀问题\n\n**支持的redis版本**: redis \u003e= 5.0  \n**优点**：可以运行在低版本的redis中（redis \u003e= 5.0 ）      \n**缺点**：过期淘汰效率较低（相对SORT模式而言，特别是redis中含有过多的干扰key时）  \n\n**使用方式**：以默认选项执行cmake，并重新编译\n### SORT_MODE（排序模式）：\n\n- 使用两级排序索引，第一级对tairhash主key进行排序，第二级针对每个tairhash内部的field进行排序\n- 第一级排序使用第二级排序里最小的ttl进行排序，因此主key是按照ttl全局有序的\n- 内置定时器会周期扫描第一级索引，找出一部分已经过期的key，然后分别再检查这些key的二级索引，进行field的淘汰，也就是active expire\n- 排序中所有的key和field都是指针引用，无内存拷贝，无内存膨胀问题\n\n**支持的redis版本**: redis \u003e= 7.0  \n**优点**：过期淘汰效率比较高      \n**缺点**：更多的内存消耗  \n\n**使用方式**：cmake的时候加上`-DSORT_MODE=yes`选项，并重新编译\n### SLAB_MODE（slab模式）：\n\n- SLAB模式是一种节省内存，缓存友好，高性能的过期算法\n- 和SORT模式一样，也会依赖key的全局排序索引进行过期key的快速查找。和SORT模式不同的是，SLAB不会对key内部的field进行排序索引，相反他们是无序的，这样可以节省索引内存开销‘\n- SLAB过期算法使用SIMD指令（当硬件支持时）来加速对过期field的查找\n\n**支持的redis版本**: redis \u003e= 7.0  \n\n**优点**：高效淘汰，低内存消耗，快速访问，为过期算法带来新思路  \n\n**缺点**：更多的内存消耗  \n\n**使用方式**：cmake的时候加上`-DSLAB_MODE=yes`选项，并重新编译\n\n## 主动过期\n- 每一次读写field，会触发对这个field自身的过期淘汰操作  \n- 每次写一个field时，TairHash也会检查其它field（可能属于其它的key）是否已经过期（每次最多检查3个），因为field是按照TTL排序的，因此这个检查会很高效 (注意: SLAB_MODE暂时不支持这个功能)\n\n## 事件通知  \n\ntairhash在field发生过期时（由主动或被动过期触发）会发送一个事件通知，通知以pubsub方式发送，channel的格式为：`tairhash@\u003cdb\u003e@\u003ckey\u003e__:\u003cevent\u003e` , 目前只支持expired事件类型，因此\nchannel为：`tairhash@\u003cdb\u003e@\u003ckey\u003e__:expired`，消息内容为过期的field。\n\n## 快速开始\n\n```go\n127.0.0.1:6379\u003e EXHSET k f v ex 10\n(integer) 1\n127.0.0.1:6379\u003e EXHGET k f\n\"v\"\n127.0.0.1:6379\u003e EXISTS k\n(integer) 1\n127.0.0.1:6379\u003e debug sleep 10\nOK\n(10.00s)\n127.0.0.1:6379\u003e EXISTS k\n(integer) 0\n127.0.0.1:6379\u003e EXHGET k f\n(nil)\n127.0.0.1:6379\u003e EXHSET k f v px 10000\n(integer) 1\n127.0.0.1:6379\u003e EXHGET k f\n\"v\"\n127.0.0.1:6379\u003e EXISTS k\n(integer) 1\n127.0.0.1:6379\u003e debug sleep 10\nOK\n(10.00s)\n127.0.0.1:6379\u003e EXISTS k\n(integer) 0\n127.0.0.1:6379\u003e EXHGET k f\n(nil)\n127.0.0.1:6379\u003e EXHSET k f v  VER 1\n(integer) 1\n127.0.0.1:6379\u003e EXHSET k f v  VER 1\n(integer) 0\n127.0.0.1:6379\u003e EXHSET k f v  VER 1\n(error) ERR update version is stale\n127.0.0.1:6379\u003e EXHSET k f v  ABS 1\n(integer) 0\n127.0.0.1:6379\u003e EXHSET k f v  ABS 2\n(integer) 0\n127.0.0.1:6379\u003e EXHVER k f\n(integer) 2\n```  \n\n## Docker\n```\ndocker run -p 6379:6379 tairmodule/tairhash:latest\n```\n## 编译及使用\n\n```\nmkdir build  \ncd build  \ncmake ../ \u0026\u0026 make -j\n```\n编译成功后会在lib目录下产生tairhash_module.so库文件\n\n```\n./redis-server --loadmodule /path/to/tairhash_module.so\n```  \n## 测试方法\n\n1. 修改`tests`目录下tairhash.tcl文件中的路径为`set testmodule [file your_path/tairhash_module.so]`\n2. 将`tests`目录下tairhash.tcl文件路径加入到redis的test_helper.tcl的all_tests中\n3. 在redis根目录下运行./runtest --single tairhash\n\n## 客户端\n\n| language | GitHub |\n|----------|---|\n| Java     |https://github.com/alibaba/alibabacloud-tairjedis-sdk|\n| Python   |https://github.com/alibaba/tair-py|\n| Go       |https://github.com/alibaba/tair-go|\n| .Net     |https://github.com/alibaba/AlibabaCloud.TairSDK|\n\n## API\n[参考这里](CMDDOC-CN.md)\n\n## 我们的modules\n\n[TairHash](https://github.com/alibaba/TairHash): 和redis hash类似，但是可以为field设置expire和version，支持高效的主动过期和被动过期   \n[TairZset](https://github.com/alibaba/TairZset): 和redis zset类似，但是支持多（最大255）维排序，同时支持incrby语义，非常适合游戏排行榜场景   \n[TairString](https://github.com/alibaba/TairString): 和redis string类似，但是支持设置expire和version，并提供CAS/CAD等实用命令，非常适用于分布式锁等场景  \n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftair-opensource%2FTairHash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftair-opensource%2FTairHash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftair-opensource%2FTairHash/lists"}