yinqiwen / ardb

A redis protocol compatible nosql, it support multiple storage engines as backend like Google's LevelDB, Facebook's RocksDB, OpenLDAP's LMDB, PerconaFT, WiredTiger, ForestDB.
BSD 3-Clause "New" or "Revised" License
1.83k stars 278 forks source link

运行一段时间之后 ardb 不再处理任何请求 #481

Closed greensea closed 4 years ago

greensea commented 4 years ago

问题现象:

  1. 启动 ardb,启动后一切正常
  2. 持续运行一段时间之后,突然无法连接到 ardb,表现为:
    • 使用 redis-cli info 命令尝试连接,命令输入后没有任何返回
    • 在代码中尝试连接,30s 后报连接超时错误

问题出现后,通过 netstat 查看 ardb 的网络连接情况,发现有大量 CLOSE_WAIT 状态的连接。

如何重现: 目前没有办法重现,这个现象只在生产环境上出现,生产环境上的 ops 大概是 1k~2k,同时连接数不到 10 个,高峰时同时连接数不超过 1000 个。 我尝试在本地模拟 5000 个用户同时连接,并执行 GET, SET, HSET, HGET 等指令,试图模拟服务器状态,但未能重现。

大致分析: 在服务器出现此问题后,使用 strace 工具进行了一些分析,发现主进程会循环执行下面的操作:

epoll_wait(...),随后获得一个 fd accept4(...),随后成功创建一个与客户端的连接 write(30, "\2\0\0\0\1\0\0\0", 8) = -1 EAGAIN ...不断循环以上过程

可以看到,主进程似乎一直卡在 write(30, ...) 这个行为上无法自拔。30 这个 fd 似乎是一个 FIFO 管道。

经过进一步的调试,发现主进程应该是在向一个线程通过 FIFO 发送消息,但接收此 FIFO 消息的线程似乎一直没有去读取 FIFO 的内容。

接收这个 FIFO 的线程似乎是负责处理 redis 命令并返回结果的线程,这个线程似乎冻结住了,所以造成了上面所说的情况。

greensea commented 4 years ago

怀疑是 systemd 的锅。虽然我使用的 systemd 配置文件是从 redis.service 复制过来修改的,但也检查过一遍,没发现有什么问题。 现在不用 systemd,直接手动启动 ardb,一切正常。