建站服务器
1. Redis简介
Redis是一个开源软件项目(BSD许可),用ANSI C编写,适用于大多数的POSIX系统,是一个可用作数据库、缓存和消息代理的内存数据库。Redis是一个非关系型数据库,Redis可以存储键与五种不同数据结构类型之间的映射,这五种类型分别为:字符串、列表、集合、有序集合和散列。Redis通常将整个数据集保存在内存中,Redis通过两种不同的方式实现持久性:一种是快照,另一种是AOF(AppendOnly File)。Redis支持主从复制,来自任何Redis服务器的数据可以复制到任意数量的从站。Redis还包含发布/订阅、Lua脚本等其他功能。
2. 资源获取
在官网下载第三方中间件的资源,Redis的官方下载网站为:https://redis.io/download。本文中使用的版本是redis-3.2.8,下载后解压文件,文件目录如图 2-1所示。
图 2-1 Redis解压后的文件
src目录包含Redis的实现,tests目录包含使用tcl语言实现的单元测试,deps目录包含Redis所需要使用的库,SylixOS只需要提供libc的POSIX兼容接口以及一个C编译器即可。
3. Linux平台编译
将文件夹拷贝到Linux平台下,由于文件夹中已有Makefile文件,所以可直接编译,Makefile文件如图 3-1所示。
图 3-1 Makefile文件
Redis可以手动选择内存分配器进行编译,Redis支持libc malloc以及jemalloc,并且在Linux系统上jemalloc是默认值,因此要强制使用libc malloc编译需要添加命令参数,编译命令如图 3-2所示。
图 3-2 编译命令
4. 移植工作
Redis采用的服务器客户端模型,并且支持命令行模式以及hiredis API接口,因此需要编译出服务器的可执行程序以及根据具体需求编译出客户端的可执行程序。
4.1 服务器工程创建
在Real-Evo IDE中创建redis-server的应用工程,删除工程中src目录下的redis-server.c文件,导入源码包中的src和deps两个文件夹。导入完成后的工程文件如图 4-1所示。
图 4-1 工程文件
改为专家模式,修改源文件和头文件路径,头文件路径如图 4-2所示。
图 4-2 头文件路径
部分源文件如图 4 3所示。
图 4-3 源文件名
链接base工程内的cextern动态库,如图 4-4所示。
图 4-4 链接cextern动态库
由于SylixOS支持endian.h头文件,因此注释config.h内的部分代码,并直接包含头文件,具体如程序清单 4-1所示。
程序清单 4-1 config.h代码修改
#if 0
#ifndef BYTE_ORDER
#if (BSD >= 199103)
# include<machine/endian.h>
#else
#if defined(linux) ||defined(__linux__)
# include<endian.h>
#else
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax,pc) */
#define BIG_ENDIAN 4321 /* most-significant byte first(IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first inlong (pdp)*/
#if defined(__i386__) ||defined(__x86_64__) || defined(__amd64__) || \\
defined(vax) || defined(ns32000) || defined(sun386) || \\
defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \\
defined(__alpha__) || defined(__alpha)
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(sel) || defined(pyr) ||defined(mc68000) || defined(sparc) || \\
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370)|| \\
defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX)||\\
defined(apollo) || defined(__convex__) || defined(_CRAY) || \\
defined(__hppa) || defined(__hp9000) || \\
defined(__hp9000s300) || defined(__hp9000s700) || \\
defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc)
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif/*linux */
#endif/* BSD */
#endif/* BYTE_ORDER */
#endif
#include<endian.h>
部分代码变量在使用时定义,错误如图 4-5所示。
图 4-5 使用时定义的错误
修改编译器选项,具体配置如图 4-6所示。
图 4-6 配置编译器
代码中有多个main入口,由于需要生成服务器的可执行文件,因此需要注释掉多余的main入口,只需要保留server.c的main入口。
部分代码中函数名一致,导致编译报错,因此需要为对应的函数加static修饰,报错如图 4-7所示。
图 4-7 函数重定义错误
由于SylixOS默认栈空间大小无法满足服务器对栈空间的需求,因此修改栈空间大小,具体代码如程序清单 4-2所示。
程序清单 4-2 设置栈空间大小
int main(intargc,char **argv) {
LW_CLASS_THREADATTR threadAttr;
LW_HANDLE hThreadId;
__GiArgc = argc;
__GppcArgv = argv;
Lw_ThreadAttr_Build(&threadAttr,
350 * LW_CFG_KB_SIZE,
LW_PRIO_NORMAL,
LW_OPTION_THREAD_STK_CHK,
LW_NULL);
hThreadId = Lw_Thread_Create(t_server, redisServer, &threadAttr, LW_NULL);
if (hThreadId ==LW_OBJECT_HANDLE_INVALID) {
return (PX_ERROR);
}
Lw_Thread_Join(hThreadId,NULL);
return ERROR_NONE;
}
SylixOS下rename的实现是用新文件直接替换原文件,由于原文件已经存在可能导致替换失败,因此在rename前需要先删除原文件,具体代码如程序清单 4-3所示。
程序清单 4 3 rename的使用
unlink(filename);
if (rename(tmpfile,filename) == -1) {
serverLog(LL_WARNING,Error movingtempappend only file on the final destination: %s,strerror(errno));
unlink(tmpfile);
return C_ERR;
}
将工程文件内的fork通过posix_spawn函数进行功能替换,替换完成后编译工程,生成服务器的可执行程序即可。
4.2 动态库工程创建
创建libredis动态库工程,删除libredis.c文件,导入hiredis文件夹,工程如图 4-8所示。
图 4-8 动态库工程
链接cextern动态库,在专家模式下修改源文件和头文件目录,如图 4-9所示。
图 4-9 源文件和头文件路径
编译完成即可。
5. Redis的使用
运行服务器,redis.conf为服务器配置文件,可对服务器功能进行配置,运行服务器如图 5-1所示。
图 5-1 运行Redis服务器
运行测试程序,测试Redis的API功能是否正常,运行结果显示功能正常,具体现象如图 5-2所示。
图 5-2 测试用例运行结果
6. 参考资料
官网:
https://redis.io/
博客:
http://blog.csdn.net/kingqizhou/article/details/8104693
文档:
《Redis命令参考手册》
《Redis实战》