执行 zclear 命令后导致 SSDB 变慢

SSDB SortedSet 性能 NOSQL zclear

早上手雷热门列表接口出现超时警告,接口调用耗时超过1s。 经过一些分析,定位到了问题的原因。

手雷热门列表接口的实现很简单。每次分页请求,服务就从 SSDB 的 Sorted Set 中按序返回子串。 按照经验值,SSDB 完成这个调用操作不到1毫秒。

SSDB: 一个高性能的支持丰富数据结构的 NoSQL 数据库, 用于替代 Redis.

分析解决

调用参数异常

服务的逻辑很简单,主要耗时应该是在SSDB的操作中。 通过分析日志,发现有异常操作,limit的值过大:

2016-06-15 11:40:50.158 [DEBUG] worker.cpp(35): w:0.029,p:48.136, req: zrrange SlHotVideoLists:1465899988496 0 1202032895, resp: ok

猜测该操作会加载大量数据到内存,从而拖累整个 SSDB 的 zrrange 操作。 但是将这个命令贴到 ssdb-cli 中执行,发现使获取不到任何数据的。 可能是 SSDB 有做异常请求过滤吧(代码逻辑没有看到这段)。 不管怎样,还是需要把应用服务的异常请求过滤了。

解决了应用层的异常后,SSDB的慢查询还是持续。

分析慢日志

没有办法,我重启了 SSDB,并监控 SSDB 的慢查询日志。 重启后,刚开始基本上没有慢查询的日志。 跟踪 SSDB 的慢日志后,发现一个现象 —— 某个 zclear 操作后,就会出现一波慢查询。 需要 > 100ms。

猜测:SSDB 在 zclear 操作后会导致 zrrange 操作变慢。为了证明我的猜想做了横向和纵向的对比:

  • 横向:文件管理的热门视频列表也是使用的 zrrange,但是是放在另外一个 SSDB 实例上。通过监控这个实例的慢查询,发现基本上没有。并且这个实例上的 并发量 比手雷上面的高。通过分析日志,发现这个实例的应用没有调用过 zclear 命令。
  • 纵向:去除手雷应用层的 zclear 操作后,并重压缩 ssdb 数据,持续监控手雷 SSDB 实例的慢查询。发现很少会出现慢查询,且慢查询一般都是1ms 左右。

从现象上验证了唯一变量——zclear 操作,导致了服务耗时变长。

后续

以上是根据现象推测的,没有从根本上证实自己的想法。具体还是需要通过分析源码和更多的实验操作才能确定。

SSDB服务的版本信息:ssdb-server 1.9.1

吕飞

锲而舍之,朽木不折;锲而不舍,金石可镂