/zbec

朴实无华的后端缓存, 单实例百万+并发, 解决缓存击穿丶缓存雪崩丶缓存穿透, 支持任何数据库

Primary LanguageGo

朴实无华的后端缓存, 单实例百万+并发, 解决缓存击穿丶缓存雪崩丶缓存穿透, 支持任何数据库


获得

go get -u github.com/zlyuancn/zbec

解决缓存击穿

当有多个进程同时获取一个key时, 只有一个进程会真的去缓存db读取或从db加载并返回结果, 其他的进程会等待该进程结束直接收到结果. 实现方式请转到 github.com/zlyuancn/zsingleflight

解决缓存雪崩

  • 设置随机的TTL, 可以有效减小缓存雪崩的风险

解决缓存穿透

  • 可以通过 zbec.WithCacheNoEntry 开启缓存空条目(默认开启), 空条目有效时间默认为 5s
  • 可以通过 zbec.WithLocalCache 设置本地缓存
  • 在用户请求key的时候判断它是否可能不存在, 比如判断id长度不等于32(uuid去掉横杠的长度)直接返回错误

db数据库

  • 支持任何数据库, 本模块不关心用户如何加载数据

缓存数据库

编解码器

开发过程中不需要考虑每个对象的编解码, 可以在初始化时为缓存数据库时选择一个编解码器, 默认是MsgPack

以下是性能测试数据

未模拟用户请求和db加载, 直接测试本模块本身的性能

# 性能测试命令
go test -v -bench "^Benchmark_.+$" -run ^$ -cpu 20,50,100,1000,10000 .
# 下面这个是用户没有go环境但是有docker的情况下
docker run --rm -v ${PWD}/../..:/src/app -v /src/gopath:/src/gopath -v /src/gocache:/src/gocache -w /src/app/zbec/test zlyuan/golang:1.13 go test -v -bench "^Benchmark_.+$" -run ^$ -cpu 20,50,100,1000,10000 .

1000 个key, 每个key 512字节随机数据, 请求key顺序随机

# go-cache
Benchmark_GoCache1e3-20                     	 1885130	       730 ns/op
Benchmark_GoCache1e3-50                     	 1568814	       777 ns/op
Benchmark_GoCache1e3-100                    	 2048479	       744 ns/op
Benchmark_GoCache1e3-1000                   	 2303812	       642 ns/op
Benchmark_GoCache1e3-10000                  	 1705032	       716 ns/op

# redis
Benchmark_Redis1e3-20                       	   88453	     12643 ns/op
Benchmark_Redis1e3-50                       	  229730	      4961 ns/op
Benchmark_Redis1e3-100                      	  459921	      2482 ns/op
Benchmark_Redis1e3-1000                     	 2120120	       555 ns/op
Benchmark_Redis1e3-10000                    	 1548505	       722 ns/op

# redis and LocalCache
Benchmark_RedisAndLocalCache1e3-20          	 1948473	       704 ns/op
Benchmark_RedisAndLocalCache1e3-50          	 1781548	       697 ns/op
Benchmark_RedisAndLocalCache1e3-100         	 1971524	       697 ns/op
Benchmark_RedisAndLocalCache1e3-1000        	 2467428	       567 ns/op
Benchmark_RedisAndLocalCache1e3-10000       	 2359215	       539 ns/op

10 000 个key, 每个key 512字节随机数据, 请求key顺序随机

点击展开

# go-cache
Benchmark_GoCache1e4-20                     	 2310266	       495 ns/op
Benchmark_GoCache1e4-50                     	 1808149	       734 ns/op
Benchmark_GoCache1e4-100                    	 1820456	       646 ns/op
Benchmark_GoCache1e4-1000                   	 2386491	       639 ns/op
Benchmark_GoCache1e4-10000                  	 2307810	       490 ns/op

# redis Benchmark_Redis1e4-20 102188 11582 ns/op Benchmark_Redis1e4-50 229939 4651 ns/op Benchmark_Redis1e4-100 518737 2286 ns/op Benchmark_Redis1e4-1000 2165594 576 ns/op Benchmark_Redis1e4-10000 1486389 753 ns/op
# redis and LocalCache Benchmark_RedisAndLocalCache1e4-20 141720 8330 ns/op Benchmark_RedisAndLocalCache1e4-50 386697 2975 ns/op Benchmark_RedisAndLocalCache1e4-100 595728 1722 ns/op Benchmark_RedisAndLocalCache1e4-1000 2459406 516 ns/op Benchmark_RedisAndLocalCache1e4-10000 2012082 606 ns/op

100 000 个key, 每个key 512字节随机数据, 请求key顺序随机

点击展开

# go-cache
Benchmark_GoCache1e5-20                     	 1325640	       873 ns/op
Benchmark_GoCache1e5-50                     	 2432680	       625 ns/op
Benchmark_GoCache1e5-100                    	 2065634	       737 ns/op
Benchmark_GoCache1e5-1000                   	 2319595	       657 ns/op
Benchmark_GoCache1e5-10000                  	 2056987	       602 ns/op

# redis Benchmark_Redis1e5-20 96511 12034 ns/op Benchmark_Redis1e5-50 220322 5035 ns/op Benchmark_Redis1e5-100 461415 2308 ns/op Benchmark_Redis1e5-1000 2163451 615 ns/op Benchmark_Redis1e5-10000 1538402 710 ns/op
# redis and LocalCache Benchmark_RedisAndLocalCache1e5-20 99225 11235 ns/op Benchmark_RedisAndLocalCache1e5-50 248864 4999 ns/op Benchmark_RedisAndLocalCache1e5-100 427542 2480 ns/op Benchmark_RedisAndLocalCache1e5-1000 2517938 566 ns/op Benchmark_RedisAndLocalCache1e5-10000 1857760 562 ns/op

开发注意事项

  • 获取值时保存结果的变量必须是一个指针
  • 从数据库加载条目为空时应该返回zbec.ErrNoEntry错误
  • 如果你可能对结果进行修改, 为了不产生并发写错误, 你应该设置 zbec.WithDeepcopyResult(true) , 代价是性能有所降低

示例代码

即将出现...