项目作者: llr104

项目描述 :
基于go的轻量化key-value服务
高级语言: Go
项目地址: git://github.com/llr104/lightkv.git
创建时间: 2020-05-27T13:04:00Z
项目社区:https://github.com/llr104/lightkv

开源协议:MIT License

下载


lightkv 轻量化key-value缓存服务

  • 支持字符串key-value、 key-map、key-list、key-set存储
  • 可持久化到本地
  • 提供api访问和grpc访问接口
  • 简单易用

    启动server

    1. go run main/server.go
  • 会启动一个api服务(http://localhost:9981) 和一个rpc服务(9980端口)

  • api 提供的方法有 put、del、get、hput、hget、hgetm、hdelm、hdel、lget、lgetr、lput、ldel、ldelr、sget、sput、sdel、sdelm

api普通字符串(put、del、get)

api map(hput、hget、hgetm、hdelm、hdel)

api list(lget、lgetr、lput、ldel、ldelr)

api set(sget、sput、sdel、sdelm)

启动测试rpc客户端

  1. go run main/client.go

rpc 客户端用法

普通字符串 用法

  1. c := server.NewClient("127.0.0.1:9980")
  2. c.Start()
  3. defer c.Close()
  4. c.ClearValue()
  5. //添加kv
  6. c.Put("test","test_value",0)
  7. c.Put("test1/tttt","test1_value",0)
  8. c.Put("test2","test2_value",5)
  9. c.Put("test3","test3_value",5)
  10. v := c.Get("test2")
  11. log.Printf("获取 test2 的值:%s", v)
  12. //删除kv
  13. c.Del("test2")
  14. log.Printf("删除 test2 之后的值:%s", c.Get("test2"))
  15. //监听key值,发生变化回调通知
  16. c.WatchKey("watch1", func(k string, beforeV string, afterV string, t kv.OpType) {
  17. if t == kv.Add {
  18. log.Printf("监听的 key:%s 新增了, 变化前:%s\n变化后:%s\n", k, beforeV, afterV)
  19. }else if t == kv.Del {
  20. log.Printf("监听的 key:%s 删除了, 变化前:%s\n变化后:%s\n", k, beforeV, afterV)
  21. }
  22. })
  23. //key值发生变化回调通知
  24. c.WatchKey("unwatch", func(k string, beforeV string, afterV string, t kv.OpType) {
  25. if t == kv.Add {
  26. log.Printf("监听的 key:%s 新增了, 变化前:%s\n变化后:%s\n", k, beforeV, afterV)
  27. }else if t == kv.Del {
  28. log.Printf("监听的 key:%s 删除了, 变化前:%s\n变化后:%s\n", k, beforeV, afterV)
  29. }
  30. })
  31. c.WatchKey("watchdel", func(k string, beforeV string, afterV string, t kv.OpType) {
  32. if t == kv.Add {
  33. log.Printf("监听的 key:%s 新增了, 变化前:%s\n变化后:%s\n", k, beforeV, afterV)
  34. }else if t == kv.Del {
  35. log.Printf("监听的 key:%s 删除了, 变化前:%s\n变化后:%s\n", k, beforeV, afterV)
  36. }
  37. })
  38. c.Put("unwatch", "this is before unwatch", 0)
  39. time.Sleep(1*time.Second)
  40. //取消监听key值的变化
  41. c.UnWatchKey("unwatch")
  42. c.Put("watch1", "this is watch1", 0)
  43. c.Put("unwatch", "this is after unwatch", 0)
  44. c.Put("watchdel", "this is watchdel", 0)
  45. log.Printf("获取 watchdel:%s", c.Get("watchdel"))
  46. c.Del("watchdel")
  47. log.Printf("获取 unwatch:%s", c.Get("unwatch"))

map 用法

  1. c := server.NewClient("127.0.0.1:9980")
  2. c.Start()
  3. defer c.Close()
  4. c.ClearMap()
  5. keys := []string{"k1", "k2", "k3"}
  6. vals := []string{"v1", "v2", "v3"}
  7. //新增map
  8. c.HMPut("hmtest1", keys, vals, 0)
  9. str := c.HMGet("hmtest1")
  10. log.Printf("获取hmtest1 map:\n%s", str)
  11. //删除hmtest1 map 中的k1
  12. c.HMDelMember("hmtest1", "k1")
  13. str = c.HMGet("hmtest1")
  14. log.Printf("hmtest1 map 删除了k1后:\n%s", str)
  15. c.HMDel("hmtest1")
  16. log.Printf("删除hmtest1 map后,hmtest1的值:\n%s", c.HMGet("hmtest1"))
  17. c.HMWatch("hmtest2", "", func(hk string, k string, beforeV string, afterV string, t kv.OpType) {
  18. if k == ""{
  19. if t == kv.Add {
  20. log.Printf("监听的 map key:%s, 新增了, 变化前:%s\n变化后:%s\n", hk, beforeV, afterV)
  21. }else if t == kv.Del {
  22. log.Printf("监听的 map key:%s, 删除了, 变化前:%s\n变化后:%s\n", hk, beforeV, afterV)
  23. }
  24. }else{
  25. if t == kv.Add {
  26. log.Printf("监听的 map key:%s, 元素:%s, 新增了, 变化前:%s\n变化后:%s\n", hk, k, beforeV, afterV)
  27. }else if t == kv.Del {
  28. log.Printf("监听的 map key:%s, 元素:%s, 删除了,变化前:%s\n变化后:%s\n", hk, k, beforeV, afterV)
  29. }
  30. }
  31. })
  32. c.HMWatch("hmtest2", "k1", func(hk string, k string, beforeV string, afterV string, t kv.OpType) {
  33. if k == ""{
  34. if t == kv.Add {
  35. log.Printf("监听的 map key:%s, 新增了, 变化前:%s\n变化后:%s\n", hk, beforeV, afterV)
  36. }else if t == kv.Del {
  37. log.Printf("监听的 map key:%s, 删除了, 变化前:%s\n变化后:%s\n", hk, beforeV, afterV)
  38. }
  39. }else{
  40. if t == kv.Add {
  41. log.Printf("监听的 map key:%s, 元素:%s, 新增了, 变化前:%s\n变化后值为:\n%s", hk, k, beforeV, afterV)
  42. }else if t == kv.Del {
  43. log.Printf("监听的 map key:%s, 元素:%s, 删除了, 变化前:%s\n变化后值为:\n%s", hk, k, beforeV, afterV)
  44. }
  45. }
  46. })
  47. c.HMWatch("hmtest2", "", func(hk string, k string, beforeV string, afterV string, t kv.OpType) {
  48. if k == ""{
  49. if t == kv.Add {
  50. log.Printf("监听的 map key:%s, 新增了, 变化前:%s\n变化后:%s\n", hk, beforeV, afterV)
  51. }else if t == kv.Del {
  52. log.Printf("监听的 map key:%s, 删除了, 变化前:%s\n变化后:%s\n", hk, beforeV, afterV)
  53. }
  54. }else{
  55. if t == kv.Add {
  56. log.Printf("监听的 map key:%s, 元素:%s, 新增了, 变化前:%s\n变化后:%s\n", hk, k, beforeV, afterV)
  57. }else if t == kv.Del {
  58. log.Printf("监听的 map key:%s, 元素:%s, 删除了, 变化前:%s\n变化后:%s\n", hk, k, beforeV, afterV)
  59. }
  60. }
  61. })
  62. log.Printf("新增hmtest2 map")
  63. //新增hmtest2 map
  64. c.HMPut("hmtest2", keys, vals, 3)
  65. log.Printf("获取 hmtest2 map的值:\n%s", c.HMGet("hmtest2"))
  66. log.Printf("获取hmtest2 map 中k2元素:%s", c.HMGetMember("hmtest2", "k2"))
  67. //删除hmtest2 中的k2
  68. log.Printf("删除hmtest2 map 中k1元素")
  69. c.HMDelMember("hmtest2", "k1")
  70. c.HMPut("hmtest3", keys, vals, 0)
  71. log.Printf("获取hmtest2 map 中k1元素:%s", c.HMGetMember("hmtest2", "k1"))

list 用法

  1. c := server.NewClient("127.0.0.1:9980")
  2. c.Start()
  3. defer c.Close()
  4. c.ClearList()
  5. c.LPut("testlist", []string{"1","2", "3"}, 10)
  6. c.LPut("list1", []string{"a1","a2", "a3"}, 0)
  7. arr, _ := c.LGet("list1")
  8. log.Printf("获取list1:%v", arr)
  9. c.LPut("list2", []string{"b1","b2", "b3", "b4", "b5"}, 0)
  10. arr, _ = c.LGet("list2")
  11. log.Printf("获取list2:%v", arr)
  12. arr, _ = c.LGetRange("list2", 0,2)
  13. log.Printf("获取list2 0-2:元素%v", arr)
  14. log.Printf("删除list2 1-3位元素")
  15. c.LDelRange("list2", 1,3)
  16. arr, _ = c.LGet("list2")
  17. log.Printf("获取list2:%v", arr)
  18. c.LWatchKey("watchList", func(k string, beforeV []string, afterV []string, opType kv.OpType) {
  19. if opType == kv.Add {
  20. log.Printf("监听 %s 新增了, 变化前:%v\n变化后:%v\n", k, beforeV, afterV)
  21. }else{
  22. log.Printf("监听 %s 删除了, 变化前:%v\n变化后:%v\n", k, beforeV, afterV)
  23. }
  24. })
  25. log.Printf("添加watchList")
  26. c.LPut("watchList", []string{"c1", "c2", "c3", "c4", "c5"}, 0)
  27. log.Printf("删除watchList的0-2元素")
  28. c.LDelRange("watchList", 0,2)
  29. log.Printf("取消监听watchList")
  30. c.LUnWatchKey("watchList")
  31. log.Printf("删除watchList")
  32. c.LDel("watchList")
  33. arr, _ = c.LGet("watchList")
  34. log.Printf("获取watchList:%v", arr)

set 用法

  1. c := server.NewClient("127.0.0.1:9980")
  2. c.Start()
  3. defer c.Close()
  4. c.ClearSet()
  5. c.SPut("set1", []string{"aset","bset", "cset", "aset"}, 0)
  6. arr, _:= c.SGet("set1")
  7. log.Printf("获取set1:%v", arr)
  8. arr, _= c.SGet("set2")
  9. log.Printf("在没有存入set2时获取set2:%v", arr)
  10. c.SPut("set2", []string{"aset2","bset2", "cset2", "aset2"}, 0)
  11. arr, _= c.SGet("set2")
  12. log.Printf("存入set2后获取set2:%v", arr)
  13. log.Printf("删除set2的cset2元素")
  14. c.SDelMember("set2", "cset2")
  15. arr, _= c.SGet("set2")
  16. log.Printf("获取set2:%v", arr)
  17. log.Printf("删除set1")
  18. c.SDel("set1")
  19. arr, _ = c.SGet("set1")
  20. log.Printf("获取set1:%v", arr)
  21. c.SWatchKey("setwatch", func(key string, before []string, after []string, opType kv.OpType) {
  22. if opType == kv.Add {
  23. log.Printf("监听 %s 新增了,新增前的值为:%v\n新增后的值为:%v\n", key, before, after)
  24. }else{
  25. log.Printf("监听 %s 删除了,删除前的值为:%v\n删除后的值为:%v\n", key, before, after)
  26. }
  27. })
  28. c.SPut("setwatch", []string{"setwatch1","setwatch2", "setwatc3", "setwatch4"}, 0)
  29. c.SDelMember("setwatch", "setwatch1")
  30. c.SDel("setwatch")

后续计划

  • 支持list、set 结构存储 (已完成)
  • 常用的参数支持配置 (已完成)
  • 支持配置缓存占用大小,lru算法 (已完成)
  • 分布式
  • terminal客户端