{"id":13393968,"url":"https://github.com/tidwall/redcon","last_synced_at":"2025-05-14T16:02:30.537Z","repository":{"id":38325264,"uuid":"64404140","full_name":"tidwall/redcon","owner":"tidwall","description":"Redis compatible server framework for Go","archived":false,"fork":false,"pushed_at":"2025-05-09T01:28:56.000Z","size":141,"stargazers_count":2214,"open_issues_count":14,"forks_count":165,"subscribers_count":44,"default_branch":"master","last_synced_at":"2025-05-09T02:28:43.813Z","etag":null,"topics":["golang","networking","protocol","redis"],"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/tidwall.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":"2016-07-28T14:52:34.000Z","updated_at":"2025-05-09T01:36:18.000Z","dependencies_parsed_at":"2023-02-16T02:00:24.223Z","dependency_job_id":"46fd28e0-0007-4528-b0fc-ded1fc41e539","html_url":"https://github.com/tidwall/redcon","commit_stats":{"total_commits":116,"total_committers":10,"mean_commits":11.6,"dds":0.08620689655172409,"last_synced_commit":"9f71787fcde3a344846f585ee885acfd4c933925"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fredcon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fredcon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fredcon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fredcon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tidwall","download_url":"https://codeload.github.com/tidwall/redcon/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254179903,"owners_count":22027884,"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":["golang","networking","protocol","redis"],"created_at":"2024-07-30T17:01:04.064Z","updated_at":"2025-05-14T16:02:30.519Z","avatar_url":"https://github.com/tidwall.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n\u003cimg \n    src=\"logo.png\" \n    width=\"336\" border=\"0\" alt=\"REDCON\"\u003e\n\u003cbr\u003e\n\u003ca href=\"https://godoc.org/github.com/tidwall/redcon\"\u003e\u003cimg src=\"https://img.shields.io/badge/api-reference-blue.svg?style=flat-square\" alt=\"GoDoc\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eRedis compatible server framework for Go\u003c/p\u003e\n\nFeatures\n--------\n- Create a [Fast](#benchmarks) custom Redis compatible server in Go\n- Simple interface. One function `ListenAndServe` and two types `Conn` \u0026 `Command`\n- Support for pipelining and telnet commands\n- Works with Redis clients such as [redigo](https://github.com/garyburd/redigo), [redis-py](https://github.com/andymccurdy/redis-py), [node_redis](https://github.com/NodeRedis/node_redis), and [jedis](https://github.com/xetorthio/jedis)\n- [TLS Support](#tls-example)\n- Compatible pub/sub support\n- Multithreaded\n\n*This library is also available for [Rust](https://github.com/tidwall/redcon.rs) and [C](https://github.com/tidwall/redcon.c).*\n\nInstalling\n----------\n\n```\ngo get -u github.com/tidwall/redcon\n```\n\nExample\n-------\n\nHere's a full example of a Redis clone that accepts:\n\n- SET key value\n- GET key\n- SETNX key value\n- DEL key\n- PING\n- QUIT\n- PUBLISH channel message\n- SUBSCRIBE channel\n\nYou can run this example from a terminal:\n\n```sh\ngo run example/clone.go\n```\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/tidwall/redcon\"\n)\n\nvar addr = \":6380\"\n\nfunc main() {\n\tvar mu sync.RWMutex\n\tvar items = make(map[string][]byte)\n\tvar ps redcon.PubSub\n\tgo log.Printf(\"started server at %s\", addr)\n\terr := redcon.ListenAndServe(addr,\n\t\tfunc(conn redcon.Conn, cmd redcon.Command) {\n\t\t\tswitch strings.ToLower(string(cmd.Args[0])) {\n\t\t\tdefault:\n\t\t\t\tconn.WriteError(\"ERR unknown command '\" + string(cmd.Args[0]) + \"'\")\n\t\t\tcase \"ping\":\n\t\t\t\tconn.WriteString(\"PONG\")\n\t\t\tcase \"quit\":\n\t\t\t\tconn.WriteString(\"OK\")\n\t\t\t\tconn.Close()\n\t\t\tcase \"set\":\n\t\t\t\tif len(cmd.Args) != 3 {\n\t\t\t\t\tconn.WriteError(\"ERR wrong number of arguments for '\" + string(cmd.Args[0]) + \"' command\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmu.Lock()\n\t\t\t\titems[string(cmd.Args[1])] = cmd.Args[2]\n\t\t\t\tmu.Unlock()\n\t\t\t\tconn.WriteString(\"OK\")\n\t\t\tcase \"get\":\n\t\t\t\tif len(cmd.Args) != 2 {\n\t\t\t\t\tconn.WriteError(\"ERR wrong number of arguments for '\" + string(cmd.Args[0]) + \"' command\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmu.RLock()\n\t\t\t\tval, ok := items[string(cmd.Args[1])]\n\t\t\t\tmu.RUnlock()\n\t\t\t\tif !ok {\n\t\t\t\t\tconn.WriteNull()\n\t\t\t\t} else {\n\t\t\t\t\tconn.WriteBulk(val)\n\t\t\t\t}\n\t\t\tcase \"setnx\":\n\t\t\t\tif len(cmd.Args) != 3 {\n\t\t\t\t\tconn.WriteError(\"ERR wrong number of arguments for '\" + string(cmd.Args[0]) + \"' command\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmu.RLock()\n\t\t\t\t_, ok := items[string(cmd.Args[1])]\n\t\t\t\tmu.RUnlock()\n\t\t\t\tif ok {\n\t\t\t\t\tconn.WriteInt(0)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmu.Lock()\n\t\t\t\titems[string(cmd.Args[1])] = cmd.Args[2]\n\t\t\t\tmu.Unlock()\n\t\t\t\tconn.WriteInt(1)\n\t\t\tcase \"del\":\n\t\t\t\tif len(cmd.Args) != 2 {\n\t\t\t\t\tconn.WriteError(\"ERR wrong number of arguments for '\" + string(cmd.Args[0]) + \"' command\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmu.Lock()\n\t\t\t\t_, ok := items[string(cmd.Args[1])]\n\t\t\t\tdelete(items, string(cmd.Args[1]))\n\t\t\t\tmu.Unlock()\n\t\t\t\tif !ok {\n\t\t\t\t\tconn.WriteInt(0)\n\t\t\t\t} else {\n\t\t\t\t\tconn.WriteInt(1)\n\t\t\t\t}\n\t\t\tcase \"publish\":\n\t\t\t\tif len(cmd.Args) != 3 {\n\t\t\t\t\tconn.WriteError(\"ERR wrong number of arguments for '\" + string(cmd.Args[0]) + \"' command\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconn.WriteInt(ps.Publish(string(cmd.Args[1]), string(cmd.Args[2])))\n\t\t\tcase \"subscribe\", \"psubscribe\":\n\t\t\t\tif len(cmd.Args) \u003c 2 {\n\t\t\t\t\tconn.WriteError(\"ERR wrong number of arguments for '\" + string(cmd.Args[0]) + \"' command\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcommand := strings.ToLower(string(cmd.Args[0]))\n\t\t\t\tfor i := 1; i \u003c len(cmd.Args); i++ {\n\t\t\t\t\tif command == \"psubscribe\" {\n\t\t\t\t\t\tps.Psubscribe(conn, string(cmd.Args[i]))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tps.Subscribe(conn, string(cmd.Args[i]))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tfunc(conn redcon.Conn) bool {\n\t\t\t// Use this function to accept or deny the connection.\n\t\t\t// log.Printf(\"accept: %s\", conn.RemoteAddr())\n\t\t\treturn true\n\t\t},\n\t\tfunc(conn redcon.Conn, err error) {\n\t\t\t// This is called when the connection has been closed\n\t\t\t// log.Printf(\"closed: %s, err: %v\", conn.RemoteAddr(), err)\n\t\t},\n\t)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n```\n\nTLS Example\n-----------\n\nRedcon has full TLS support through the `ListenAndServeTLS` function.\n\nThe [same example](example/tls/clone.go) is also provided for serving Redcon over TLS. \n\n```sh\ngo run example/tls/clone.go\n```\n\nBenchmarks\n----------\n\n**Redis**: Single-threaded, no disk persistence.\n\n```\n$ redis-server --port 6379 --appendonly no\n```\n```\nredis-benchmark -p 6379 -t set,get -n 10000000 -q -P 512 -c 512\nSET: 941265.12 requests per second\nGET: 1189909.50 requests per second\n```\n\n**Redcon**: Single-threaded, no disk persistence.\n\n```\n$ GOMAXPROCS=1 go run example/clone.go\n```\n```\nredis-benchmark -p 6380 -t set,get -n 10000000 -q -P 512 -c 512\nSET: 2018570.88 requests per second\nGET: 2403846.25 requests per second\n```\n\n**Redcon**: Multi-threaded, no disk persistence.\n\n```\n$ GOMAXPROCS=0 go run example/clone.go\n```\n```\n$ redis-benchmark -p 6380 -t set,get -n 10000000 -q -P 512 -c 512\nSET: 1944390.38 requests per second\nGET: 3993610.25 requests per second\n```\n\n*Running on a MacBook Pro 15\" 2.8 GHz Intel Core i7 using Go 1.7*\n\nContact\n-------\nJosh Baker [@tidwall](http://twitter.com/tidwall)\n\nLicense\n-------\nRedcon source code is available under the MIT [License](/LICENSE).\n","funding_links":[],"categories":["Go","开源类库","Open source library"],"sub_categories":["数据库","Database"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fredcon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftidwall%2Fredcon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fredcon/lists"}