{"id":13411971,"url":"https://github.com/xgzlucario/rotom","last_synced_at":"2026-01-14T23:32:34.094Z","repository":{"id":102544006,"uuid":"595713983","full_name":"xgzlucario/rotom","owner":"xgzlucario","description":"A tiny Redis server built with Golang, compatible with RESP protocols.","archived":false,"fork":false,"pushed_at":"2024-10-29T17:18:20.000Z","size":1696,"stargazers_count":41,"open_issues_count":0,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-29T18:44:27.082Z","etag":null,"topics":["aeloop","db","epoll","go","golang","lua","redis","resp","tinyredis"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xgzlucario.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":"2023-01-31T16:58:04.000Z","updated_at":"2024-10-28T03:04:48.000Z","dependencies_parsed_at":"2024-01-11T09:12:49.325Z","dependency_job_id":"a9500da4-3ea8-460a-980a-380ab1a3c7cf","html_url":"https://github.com/xgzlucario/rotom","commit_stats":{"total_commits":96,"total_committers":3,"mean_commits":32.0,"dds":0.02083333333333337,"last_synced_commit":"3ee3e58ffa6710c0550ad10d20e31281c1b785fb"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/xgzlucario/rotom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xgzlucario%2Frotom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xgzlucario%2Frotom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xgzlucario%2Frotom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xgzlucario%2Frotom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xgzlucario","download_url":"https://codeload.github.com/xgzlucario/rotom/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xgzlucario%2Frotom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28438527,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T22:37:52.437Z","status":"ssl_error","status_checked_at":"2026-01-14T22:37:31.496Z","response_time":107,"last_error":"SSL_read: 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":["aeloop","db","epoll","go","golang","lua","redis","resp","tinyredis"],"created_at":"2024-07-30T20:01:19.662Z","updated_at":"2026-01-14T23:32:34.022Z","avatar_url":"https://github.com/xgzlucario.png","language":"Go","funding_links":[],"categories":["Database","数据库","Data Integration Frameworks"],"sub_categories":["Databases Implemented in Go","Go中实现的数据库"],"readme":"# Rotom\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/xgzlucario/rotom)](https://goreportcard.com/report/github.com/xgzlucario/rotom) [![Go Reference](https://pkg.go.dev/badge/github.com/xgzlucario/rotom.svg)](https://pkg.go.dev/github.com/xgzlucario/rotom) ![](https://img.shields.io/github/languages/code-size/xgzlucario/rotom.svg) [![codecov](https://codecov.io/gh/xgzlucario/rotom/graph/badge.svg?token=2V0HJ4KO3E)](https://codecov.io/gh/xgzlucario/rotom) [![tests](https://github.com/xgzlucario/rotom/actions/workflows/rotom.yml/badge.svg)](https://github.com/xgzlucario/rotom/actions/workflows/rotom.yml) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n\nEnglish | [中文](README_CN.md)\n\n## Introduction\n\nThis is rotom, a high performance, low latency tiny Redis Server written in Go. It replicates the core event loop mechanism AeLoop in Redis based on I/O multiplexing.\n\n## Features\n\n- Implements the AeLoop single-threaded event loop from Redis using the epoll network model.\n- Excellent optimization, achieving native Redis performance.\n- Compatible with the Redis RESP protocol, allowing any Redis client to connected.\n- Implements data structures String, Hash, Set, List, ZSet.\n- Supports RDB \u0026 AOF.\n- Supports 20+ commonly used commands.\n\n## AELoop\n\nAeLoop (Async Event Loop) is the core asynchronous event-driven mechanism in Redis, which mainly includes:\n\n![img](asserts/aeloop.png)\n\n1. FileEvent: Uses I/O multiplexing to handle read and write events on network sockets, categorized into `READABLE` and `WRITABLE`.\n2. TimeEvent: Handles tasks that need to be executed after a delay or periodically, such as expiring items every `100ms`.\n3. When events are ready, they are processed by callback functions bound to those events.\n\nIn rotom, the AeLoop event loop mechanism in Redis is replicated, specifically:\n\n1. When a new TCP connection arrives, the `AcceptHandler` obtains the socket fd and adds it to the event loop, registering a read event.\n2. When the read event is ready, `ReadQueryFromClient` reads buffered data into `queryBuf`.\n3. `ProcessQueryBuf` parses and executes the corresponding commands from `queryBuf`.\n4. The command execution result is saved, and the socket fd's write event is registered.\n5. When the write event is ready, `SendReplyToClient` writes all results back to the client. A write event may return multiple read event results at once.\n6. Resources are released, and the process continues until the service is shut down.\n\n## Data Structures\n\nRotom has made several optimizations in data structures:\n\n- dict: Rotom uses `stdmap` as the db hash table, with built-in progressive rehashing.\n- hash: Based on `zipmap` with higher memory efficiency.\n- set: Uses `zipset` when the set is small and `mapset` when it is large.\n- list: Uses a `quicklist` based on `listpack` for a doubly linked list.\n- zset: Uses `zipzset` when small and `hash` + `skiplist` when it is large.\n\nNotably, `zipmap` and `zipset` are space-efficient data structures based on `listpack`, which is a new compressed list proposed by Redis to replace `ziplist`, supporting both forward and reverse traversal and solving the cascading update issue in `ziplist`.\n\n## Benchmark\n\n![img](asserts/bench.jpg)\n\nThe test will run rotom on the same machine with `appendonly` disabled, and use `redis-benchmark` tool to test the latency of different commands.\n\n```\ngoos: linux\ngoarch: amd64\npkg: github.com/xgzlucario/rotom\ncpu: 13th Gen Intel(R) Core(TM) i5-13600KF\n```\n\n## Roadmap\n\n- [ ] Support for LRU cache and memory eviction.\n- [ ] Gradually rehashing in dict.\n- [ ] RDB and AOF Rewrite.\n\n## Usage\n\n**Running Locally**\n\nFirst, clone the project to your local machine:\n\n```bash\ngit clone https://github.com/xgzlucario/rotom\n```\n\nEnsure your local Go environment is \u003e= `1.22`. In the project directory, run `go run .` to start the service, which listens on port `6379` by default:\n\n```\n$ go run .\n2024-07-18 23:37:13 DBG \n ________      _____                  \n ___  __ \\_______  /_____________ ___   Rotom 64 bit (amd64/linux)\n __  /_/ /  __ \\  __/  __ \\_  __ '__ \\  Port: 6379, Pid: 15817\n _  _, _// /_/ / /_ / /_/ /  / / / / /  Build: \n /_/ |_| \\____/\\__/ \\____//_/ /_/ /_/\n\n2024-07-18 23:37:13 INF read config file config=config.json\n2024-07-18 23:37:13 INF rotom server is ready to accept.\n```\n\n**Running in a Container**\n\nAlternatively, you can run it in a container. First, build the Docker image by running `make build-docker`:\n\n```\nREPOSITORY       TAG           IMAGE ID       CREATED         SIZE\nrotom            latest        0cd91943967a   5 seconds ago   20.9MB\n```\n\nThen, start the container:\n\n```bash\ndocker run --rm -p 6379:6379 --name rotom rotom:latest\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxgzlucario%2Frotom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxgzlucario%2Frotom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxgzlucario%2Frotom/lists"}