个人环境
- 操作系统:Ubuntu22.04 LTS
- gcc版本:11.4.0
- musl版本:1.2.2
编译Redis
使用脚本自动编译
-
安装linux-headers
sudo apt install linux-headers-$(uname -r)
-
下载Makefile
Makefile.md (2.1 KB) -
命令行输入
make
即可自动下载源码编译
-
将编译后的redis-server、redis.conf文件拷贝到DragonOS目录的bin/sysroot/bin
编译时出现的问题
-
Redis版本为5.0.7及更低版本,可能出现编译错误:
multiple definition of
SDS_NOINIT’`解决方法:更换Redis版本
-
Redis版本为**6.2.0并启用了
MALLOC=libc
,**可能出现编译错误:
解决方法:1. 更换Redis版本 2. 取消MALLOC=libc
3. 修改源代码,见:https://github.com/redis/redis/issues/8530#issuecomment-784899849
运行
步骤
-
启动DragonOS,进入/bin目录
-
输入命令
redis-server redis.conf
-
出现启动画面并且不报错说明成功启动
-
本地运行命令
redis-cli -h 127.0.0.1 -p 12580
出现前缀说明连接成功
运行时出现的问题
-
Redis使用
listen
系统调用时默认设置backlog参数为511,超出目前内核承载上限,会触发panic,并且错误信息无法正常打印,会卡在第一行
需要修改函数即可打印信息
可以看见是内核分配器触发panic,大概率是内存溢出,因此需要在redis.conf将tcp-backlog设置为420以下
-
如果编译时未将源码中的
MAX_ACCEPTS_PER_CALL
的值修改为1,会导致连接redis时阻塞,具体步骤:-
将源代码或Makefile中的
MAX_ACCEPTS_PER_CALL
修改为2 -
启动DragonOS,运行redis-server
-
本地开启两个终端,其中一个连接redis,会发现阻塞:
-
另一个连接redis,发现两个终端同时连接上
猜测是因为Redis接收连接是采用非阻塞accept方法(使用
fcntl
将socket设置为O_NONBLOCK),而目前DragonOS无法将socket设置为非阻塞,因此当连接数少于MAX_ACCEPTS_PER_CALL
的值时连接会被阻塞,直到连接数达到数量为止 -
可能的优化方向
- 优化内存管理模块和
listen
系统调用,支持更大的backlog - 实现非阻塞的
accept
调用,避免多连接的阻塞