程序员怎么用好内存数据库Redis?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序员怎么用好内存数据库Redis?相关的知识,希望对你有一定的参考价值。

程序员怎么用好内存数据库Redis?

前言:Redis是Remote Dictionary Server的缩写,意即远程字典服务器,但是更经常被用作内存数据库和缓存。在现代软件常用的微服务架构(MSA)中,Redis占有十分重要的地位,它是解决低响应时间和大并发数量的关键方法之一。因此,学好原理、用好细节成为程序员的必修课程。


1.源码分析和编译

1.1概述

Redis是Remote Dictionary Server的缩写,意即远程字典服务器。

(1)源码位置

其源码放在官网redis.io中,下载地址:https://redis.io/download

本文从gitee的副本克隆,地址:https://gitee.com/mirrors/redis.git克隆到目录F:\\work\\redis如下图,然后就可以使用gcc编译

程序员怎么用好内存数据库Redis?_客户端


如果使用vs2017编译,需要到这个地址下载:https://github.com/MicrosoftArchive/redis假设克隆到D:\\microsoftredis目录下,如下图:

程序员怎么用好内存数据库Redis?_客户端_02

(2)Redis解释

Redis有不同的称呼,有的认为是内存数据库,有的还认为是缓存服务器,还有的认为是NoSql服务器,但是称为数据结构服务器也许是最准确的。因为Redis可以通过一组命令访问可变数据结构,这些命令使用带有TCP套接字和简单协议的服务器-客户端模型发送,不同的进程可以以共享的方式查询和修改相同的数据结构。

Redis主要特点如下:

  • 关注数据结构序列化:即使数据结构是在服务器内存中提供给使用者。这意味着Redis速度很快,但也是非易失性的。
  • 实现强调内存效率:与使用高级编程语言建模的相同数据结构相比,Redis内部的数据结构可能会使用更少的内存。
  • 具有数据库特性:提供了许多在数据库中很容易找到的特性,比如复制、可调的持久性、集群和高可用性。
  • 作为memcached复杂版本:支持的操作不仅仅是set和get,还是处理复杂数据类型(如list、SETs、有序数据结构等)的操作。​

参考链接:


1.2源码分析

下面分析Redis源代码布局,每个文件中的设计思想,内部最重要的函数和结构等等。Redis代码库会不断变化,但总体设计思想不会改变太多。源码分析的主要目的还是探索用好它的途径,这适用于JAVA/C++程序员;也可以学习内存操作和数据结构操纵的有效方法,这一般适用于C/C++程序员。


1.2.1源代码布局

Redis根目录主要包含README.MD,其他文件涉及版权、运行配置文件conf和编译配置文件Makefile,可以不用关心他们。因为在src目录中才调用真正的Makefile、Redis配置和Sentinel配置。根目录还有有关Redis、Redis集群、Redis哨兵(类似于看门狗)的单元测试脚本,这些测试在tests目录中实现。

根目录下包含如下重要目录:

  • src: 包含了用C语言编写的Redis实现
  • tests: 包含用Tcl实现的单元测试
  • deps: 包含Redis使用的库。编译Redis所需的一切都在这个目录中,但是不包括libc(POSIX兼容接口)和C编译器。值得注意的是,deps包含了jemalloc的副本,这是Linux下Redis的默认分配器。在deps下也有一些始于Redis项目的东西,但其主要内容放在其他地方。
  • utils: 提供一些工具

注意:最近Redis被重构了很多。函数名和文件名已经更改,因此代码分析针对7.x版本和unstable 分支。例如,在Redis 3.0中,server.c和server.h文件被命名为Redis .c和Redis .h。然而,整体结构是相同的。


1.2.2头文件server.h

程序=算法+数据结构,先理解数据结构比先理解算法更容易,入门也相对容易。所以代码分析从Redis的主头文件server.h开始。

所有服务器配置和所有共享状态都定义在一个称为server的全局结构中,类型为struct redisServer,如下:

struct redisServer 
/* 常用*/
pid_t pid; /* 主进程 pid. */
pthread_t main_thread_id; /* 主线程 id */
char *configfile; /* 配置文件绝对路径, 或 NULL */
char *executable; /* 执行文件绝对路径 */
char **exec_argv; /* 执行参数argv向量vector (copy). */
int dynamic_hz; /* 依客户端编码而变的hz值 */
int config_hz; /* 配置的 HZ值,如果dynamic-hz激活的话,可不同于实际的hz字段值 */
mode_t umask; /* 启动进程的umask 值 */
int hz; /* serverCron() 调用频率(单位赫兹) */
int in_fork_child; /* 分叉客户端的指示 */
redisDb *db;
dict *commands; /* 指令表 */
dict *orig_commands; /* 原始指令表 */
aeEventLoop *el;
rax *errors; /* 错误表 */

......

/* 本地环境 */
char *locale_collate;
;

其中有几个重要的字段:

  • server.db是Redis数据库的数组,数据就存储在server.db中
  • server.commands是指令表
  • server.clients是连接到服务器的客户端链表
  • server.master是一个特殊的客户端,即若本实例是副本,那么server.master指向master(主节点)

该结构还有很多其他字段,大多数字段都在结构定义中有注释。

另一个重要的结构是redisClient,用于定义客户端的数据结构。过去它叫redisClient,现在只叫client。这个结构也有很多字段,如下:

typedef struct client 
uint64_t id; /* 客户端递增统一编号 */
uint64_t flags; /* 客户端标志: CLIENT_* 宏 */
connection *conn;
int resp; /* 响应协议版本,可能是2或者3 */
redisDb *db; /* 目前选中的数据库的指针 */
robj *name; /* 客户端设置名称(SETNAME)的集合 */
sds querybuf; /* 用于客户端查询的缓冲区 */
size_t qb_pos; /* querybuf中的读取位置 */
size_t querybuf_peak; /* 最近100毫秒内querybuf大小的峰值 */
int argc; /* 当前指令的参数数量 */
robj **argv; /* 当前指令的参数 */

......

size_t buf_usable_size; /* 缓冲区的可用大小 */
char *buf;
client;

client结构定义了一个可连接的客户端:

  • fd字段是客户端的socket文件描述符
  • argc和argv由客户端正在执行的命令填充,因此实现给定Redis命令的函数可以读取参数
  • querybuf收集来自客户端的请求,这些请求由Redis服务器根据Redis协议解析,并通过调用客户端正在执行的命令的实现来执行
  • Reply和buf是动态和静态缓冲区,用于收集服务器发送给客户端的响应。只要文件描述符是可写的,这些缓冲区就会增量写入套接字。

其中,argv被描述为robj结构下面是完整的robj结构,它来自redisObject:

typedef struct redisObject robj;
struct redisObject
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU时间(相对于全局lru_clock)或LFU数据(最低8位频率和最多16位访问时间)*/
int refcount;
void *ptr;
;

基本上redisObject 可以表示所有基本的Redis数据类型,比如字符串、列表、集合、有序集合等等。它有一个type字段,这样就可以知道给定对象的类型,还有一个refcount,这样就可以在多个地方引用同一个对象,而无需多次分配它。最后,ptr字段指向对象的实际表示形式,即使是同一类型,根据使用的编码方式encoding ,也可能有所不同。
Redis对象(redisObject)在Redis内部被广泛使用,但是为了避免间接访问的开销,最近在许多地方只是使用普通的动态字符串,而不是包装在Redis对象中。


1.2.3服务器入口代码server.c

这个文件是Redis服务器的入口点,因为这里面定义了main()函数,这是C语言的入口函数。如下:

int main(int argc, char **argv) 
struct timeval tv;
int j;
char config_from_stdin = 0;

......

tzset(); /* 填充全局时区 */
zmalloc_set_oom_handler(redisOutOfMemoryHandler);
/* 为了实现熵,容器的time()和getpid()可以保持一致。但是tv_usec的值足够快,可以产生不同的结果 */
gettimeofday(&tv,NULL);
srand(time(NULL)^getpid()^tv.tv_usec);
srandom(time(NULL)^getpid()^tv.tv_usec);
init_genrand64(((long long) tv.tv_sec * 1000000 + tv.tv_usec) ^ getpid());
crc64_init();

......

redisSetCpuAffinity(server.server_cpulist);
setOOMScoreAdj(-1);
aeMain(server.el);
aeDeleteEventLoop(server.el);
return 0;

下面是执行Redis服务器最重要的函数:

  • initServerConfig()设置server结构的默认值
  • initServer()分配操作、设置监听套接字等所需的数据结构
  • aeMain()启动监听新连接的事件循环

事件循环定期调用两个特殊函数

  • serverCron()根据server.hz频率定期调用,并执行必须时常执行的任务,如检查超时的客户端.
  • beforeSleep() 在每次事件循环触发时调用,Redis处理了一些请求后返回到事件循环中

在server.c中,还可以找到处理Redis服务器其他重要事情的代码:

  • call() 用于在给定客户端的上下文中调用给定命令.
  • activeExpireCycle() 处理通过EXPIRE命令设置存活时间的键的回收.
  • performEvictions(),调用于根据maxmemory判断Redis内存不足而应该执行新的写命令之时
  • 全局变量redisCommandTable定义了所有的Redis命令,指定了命令的名称、实现该命令的函数、所需参数的数量以及每个命令的其他属性.

1.2.4指令元数据代码commands.c

commands.c文件由utils/generate-command-code.py自动生成,内容基于src/commands文件夹中的JSON文件是关于Redis指令和所有关于它们的元数据的唯一来源。JSON文件不给任何人直接使用元数据可以通过COMMAND命令获得。

内容片断如下:

......

/* Main command table */
struct redisCommand redisCommandTable[] =
/* bitmap */
"bitcount","Count set bits in a string","O(N)","2.6.0",CMD_DOC_NONE,NULL,NULL,COMMAND_GROUP_BITMAP,BITCOUNT_History,BITCOUNT_tips,bitcountCommand,-2,CMD_READONLY,ACL_CATEGORY_BITMAP,NULL,CMD_KEY_RO|CMD_KEY_ACCESS,KSPEC_BS_INDEX,.bs.index=1,KSPEC_FK_RANGE,.fk.range=0,1,0,.args=BITCOUNT_Args,
"bitfield","Perform arbitrary bitfield integer operations on strings","O(1) for each subcommand specified","3.2.0",CMD_DOC_NONE,NULL,NULL,COMMAND_GROUP_BITMAP,BITFIELD_History,BITFIELD_tips,bitfieldCommand,-2,CMD_WRITE|CMD_DENYOOM,ACL_CATEGORY_BITMAP,"This command allows both access and modification of the key",CMD_KEY_RW|CMD_KEY_UPDATE|CMD_KEY_ACCESS|CMD_KEY_VARIABLE_FLAGS,KSPEC_BS_INDEX,.bs.index=1,KSPEC_FK_RANGE,.fk.range=0,1,0,bitfieldGetKeys,.args=BITFIELD_Args,

......


1.2.5 网络IO代码networking.c

networking.c定义了所有的网络I/O函数,不管是客户端相关还是主节点和副本相关,主节点和副本在Redis只是特殊的客户端。片断截取如下:

......

#include "server.h"
#include "atomicvar.h"
#include "cluster.h"

......

client *createClient(connection *conn)
client *c = zmalloc(sizeof(client));
/* 传递NULL作为conn可以创建一个非连接的客户端。这很有用,因为所有的命令在客户端上下文中都需要执行。当在其他上下文(例如一个Lua脚本)中执行命令时我们需要一个非连接客户端 */
if (conn)
connEnableTcpNoDelay(conn);
if (server.tcpkeepalive)
connKeepAlive(conn,server.tcpkeepalive);
connSetReadHandler(conn, readQueryFromClient);
connSetPrivateData(conn, c);

c->buf = zmalloc(PROTO_REPLY_CHUNK_BYTES);
selectDb(c,0);

......

主要函数包括:

  • createClient() 分配并初始化一个新客户端
  • addReply*() 函数家族,用于为了添加数据到客户端结构的命令实现,将作为执行给定命令的应答传输到客户端
  • writeToClient() 将输出缓冲区中的挂起数据传输到客户端,并由可写事件处理程序sendReplyToClient()调用。
  • readQueryFromClient() 是可读的事件处理程序,将客户端读取的数据填充到查询缓冲区中
  • processInputBuffer() 是入口点,用于根据Redis协议解析客户端查询缓冲区。一旦准备好处理命令,它就调用server.c中定义的processCommand(),以便实际执行命令
  • freeClient() 释放、断开连接并删除客户端

1.2.6 持久化代码aof.c和rdb.c

aof.crdb.c文件实现了Redis的RDB(Redis Database,快照模式)和AOF(Append Only-file,追加或日志模式)两种持久化方式。Redis使用基于fork()系统调用的持久化模型来创建一个与主Redis进程具有相同(共享)内存内容的进程。这个辅助进程将内存内容转储到磁盘上。rdb.c在磁盘上创建快照,aof.c在追加文件太大时执行AOF重写。

aof.c内部的实现有额外的函数,允许在客户端执行时将新命令追加到AOF文件中。在server.c中定义的call()函数负责调用将命令轮流写入AOF的函数,Call()函数片断如下图:

void call(client *c, int flags) 
long long dirty;
uint64_t client_old_flags = c->flags;
struct redisCommand *real_cmd = c->realcmd;
/* 初始化:清除必须由命令按需设置的标志,并初始化数组以用于其他命令传递。 */
c->flags &= ~(CLIENT_FORCE_AOF|CLIENT_FORCE_REPL|CLIENT_PREVENT_PROP);

......


1.2.7 数据库操作代码db.c

某些Redis指令操作特定的数据类型;其他的指令则是一般性的。通用指令的例子是DEL和EXPIRE,对键进行操作,而不是对键的值进行操作。所有这些通用指令都在db.c中定义。

此外,db.c实现了API可以在不直接访问内部数据结构的情况下对Redis数据集执行某些操作。

db.c中在许多命令实现中使用的最重要的函数如下

  • lookupKeyRead() 和lookupKeyWrite() 用于获取与给定键相关的值的指针,如果键不存在则使用NULL
  • dbAdd() 和它的更高级别配对函数setKey()在Redis数据库中创建一个新键
  • dbDelete() 移除键和值
  • emptyDb() 移除单个数据库或者所有数据库db.c文件的其余部分实现向客户端公开的通用命令。

1.2.8 对象处理代码object.c

前面已经描述了定义Redis对象的robj结构。在object.c中,存在所有在基本级别上操作Redis对象的函数,比如分配新对象的函数,处理引用计数等等。该文件中的重要函数如下:

  • incrRefCount()和decrRefCount()用于增加或减少对象引用计数。当它降为0时,对象最终被释放
  • createObject()分配一个新对象。还有一些专门的函数来分配具有特定内容的字符串对象,如createStringObjectFromLongLong()和类似的函数.object.c也实现了OBJECT 指令.

1.2.9 副本处理代码replication.c

这是Redis中最复杂的文件之一,其中有Redis的主节点角色和副本角色的实现。

最重要的函数之一是replicationFeedSlaves(),它将命令写入到客户端,该客户端是连接到主服务器的副本实例,因此,副本可以获得客户端执行的写操作:这样它们的数据集将与主节点中的数据集保持同步。

还实现了SYNC和PSYNC命令,用于在主节点和副本之间执行第一次同步,或在断开连接后继续处理。


1.2.10 脚本处理模块

脚本处理模块包含:

  • script.c - 脚本与Redis的集成(命令执行,设置复制/响应,…),使用script_lua.c来执行Lua代码
  • script_lua.c - 负责执行Lua代码,使用script.c从Lua代码中与Redis交互
  • function_lua.c - 包含Lua引擎实现,
  • functions.c - 包含Redis函数实现(FUNCTION命令),如果它想调用的函数需要Lua引擎,那么应使用functions_lua.c
  • eval.c - 包含使用script_lua.c调用Lua代码的eval实现

1.2.11 数据类型、集群和事件

  • t_hash.c, t_list.c, t_set.c, t_string.c, t_zset.c 和t_stream.c 包含Redis数据类型的实现。它们实现了访问给定数据类型的API,以及这些数据类型的客户端命令实现
  • ae.c 实现了Redis事件循环,它是一个自包含的库,易于阅读和理解
  • sds.c 是Redis字符串库,参考链接:https://github.com/antirez/sds
  • anet.c是一个库,与内核公开的原始接口相比,它以一种更简单的方式使用POSIX网络
  • dict.c是一个增量式复用的非阻塞哈希表的实现。
  • cluster.c实现Redis集群。可能只有在非常熟悉Redis代码库的其余部分之后才会很好地读懂它. 建议先阅读如下文档: Redis Cluster specification(Redis集群规格说明书).

1.2.12 指令剖析

所有Redis指令都按如下格式定义:

voidfoobarCommand(client *c) 
printf("%s",c->argv[1]->ptr); /* 对参数做点什么事 */
addReply(c,shared.ok); /* 应答点什么给客户端 */

命令函数由JSON文件及其元数据引用,有关详细信息,请参阅上面描述的commands.c。命令标志记录在server.h中redisCommand结构上面的注释中。其他详细信息请参见COMMAND命令,相关文档:https://redis.io/commands/command/

在命令以某种方式操作后,它会向客户端返回一个应答,通常使用addReply()或在network .c中定义的类似函数。
在Redis源代码中有大量的命令实现,可以作为实际命令实现的示例(例如pingCommand)。编写一些测试命令可以作为熟悉代码库的良好练习。


1.3 Linux下源码编译

Redis可以在Linux, OSX, OpenBSD, NetBSD, FreeBSD上编译和使用。支持大endian 和小endian 架构,以及32位和64位系统。

可以在Solaris衍生系统上编译(例如SmartOS),但对这个平台的支持是尽力,Redis不能保证在Linux、OSX和*BSD上工作得一样好。

编译如此简单:

% make

要使用TLS支持构建,需要OpenSSL开发库(例如Debian/Ubuntu上的libssl-dev)并运行:

% make BUILD_TLS=yes

要使用systemd支持进行构建,需要systemd开发库(例如Debian/Ubuntu上的libsystemd-dev或CentOS上的system -devel)并运行:

% make USE_SYSTEMD=yes

构建一个32位的Redis二进制文件

% make 32bit

在构建Redis之后,使用它进行测试

% make test

如果构建了TLS,则在启用TLS的情况下运行测试(需要安装tcl-tls):

% ./utils/gen-test-certs.sh
% ./runtest --tls


1.4 Windows下源码编译

使用VS2017打开sln文件:

程序员怎么用好内存数据库Redis?_大并发数量_03

生成解决方案:

程序员怎么用好内存数据库Redis?_微服务架构_04

得到debug版的redis系统文件:

D:\\redis-3.0.504\\redis\\msvs\\x64\\Debug

也有编译好的,下载网址:https://github.com/ServiceStack/redis-windows


2.Windows下运行


2.1环境变量和设置

在path中增加存放redis可执行文件的路径,例如:D:\\redis-3.0.504\\redis\\msvs\\x64\\Debug。

进入该进入文件夹新增文件:redis.windows.conf。

加入文本内容:

程序员怎么用好内存数据库Redis?_客户端_05


2.2 Windows下启动和测试

启动redis:

程序员怎么用好内存数据库Redis?_微服务架构_06

启动redis-cli命令行:

程序员怎么用好内存数据库Redis?_微服务架构_07

测试:

启动第一个cmd窗口:

程序员怎么用好内存数据库Redis?_微服务架构_08

启动第二个cmd窗口:

程序员怎么用好内存数据库Redis?_Redis_09

回过头来看第一个cmd窗口:

程序员怎么用好内存数据库Redis?_微服务架构_10


3.Linux下运行


3.1通用运行指令

使用默认配置运行Redis,只需输入:

% cd src
% ./redis-server

如果想使用自己的配置文件redis.conf,必须使用一个额外的参数(配置文件的路径)来运行它:

% cd src
% ./redis-server /存放路径/redis.conf

使用命令行直接将参数作为选项来更改Redis配置。例如:

% ./redis-server --port 9999 --replicaof 127.0.0.1 6379
% ./redis-server /etc/redis/6379.conf --loglevel debug

redis.conf中的所有选项也支持作为命令行的选项来使用他们有完全相同的名称。


3.2 带TLS运行

使用TLS模式手动运行Redis服务器(假设调用了 gen-test-certs.sh ,因此示例证书/密钥可用):

TLS内置模式:

./src/redis-server --tls-port 6379 --port 0 \\
--tls-cert-file ./tests/tls/redis.crt \\
--tls-key-file ./tests/tls/redis.key \\
--tls-ca-cert-file ./tests/tls/ca.crt

TLS模块模式:

./src/redis-server --tls-port 6379 --port 0 \\
--tls-cert-file ./tests/tls/redis.crt \\
--tls-key-file ./tests/tls/redis.key \\
--tls-ca-cert-file ./tests/tls/ca.crt \\
--loadmodule src/redis-tls.so

使用 Redis -cli 连接到这个Redis服务器:


./src/redis-cli --tls \\
--cert ./tests/tls/redis.crt \\
--key ./tests/tls/redis.key \\
--cacert ./tests/tls/ca.crt

这将禁用TCP并在端口6379上启用TLS。TCP和TLS也可以同时使用,但需要分配不同的端口。

要让副本用TLS连接到主服务器,使用--tls-replication yes,让Redis集群跨节点使用TLS采用如下命令--tls-cluster yes


3.3 使用CLI

可以使用Redis -cli来连接Redis。启动一个redis-server实例,然后在另一个终端尝试以下操作:

% cd src
% ./redis-cli
redis> ping
PONG
redis> set foo bar
OK
redis> get foo
"bar"
redis> incr mycounter
(integer) 1
redis> incr mycounter
(integer) 2
redis>

命令列表参见第4章。


3.4安装

为了将Redis二进制文件安装到/usr/local/bin,只需使用:

% make install

如果希望使用不同的目录,可以使用其他目录,则需要执行如下命令:

make PREFIX=/指定目录 install

make install 只会在系统中安装二进制文件,但不会在适当的位置配置init脚本和配置文件。如果只是想懂一点Redis,配置是不需要的,但如果为生产系统正确安装,那么为Ubuntu和Debian系统提供了一个脚本:

% cd utils
% ./install_server.sh

注意:install_server.sh不能在Mac OSX上运行;它仅为Linux构建。
脚本会问你一些问题,并将设置你需要正确运行Redis作为后台守护进程的一切事情,该守护进程将在系统重启时重新启动。

对于/etc/init.d/redis_6379实例,可以使用名为/etc/init.d/redis_<端口号>的脚本停止和启动Redis


4.常用指令


4.1连接命令


4.1.1启动

本地启动:redis-cli

远程启动:redis-cli -h host -p port -a password


4.1.2 AUTH password

验证密码是否正确


4.1.3 ECHO message

打印字符串


4.1.4 PING

查看服务是否运行


4.1.5 QUIT

关闭当前连接


4.1.6 SELECT index

切换到指定的数据库


4.2 keys命令


4.2.1 DEL key

DUMP key

序列化给定的key并返回序列化的值


4.2.2 EXISTS key

检查给定的key是否存在


4.2.3 EXPIRE key seconds

为key设置过期时间


4.2.4 EXPIRE key timestamp

时间戳的方式给key设置过期时间


4.2.5 PEXPIRE key milliseconds

设置key的过期时间以毫秒计


4.2.6 KEYS pattern

查找所有符合给定模式的key


4.2.7 MOVE key db

将当前数据库的key移动到数据库db当中


4.2.8 PERSIST key

移除key的过期时间,key将持久保存


4.2.9 PTTL key

以毫秒为单位返回key的剩余过期时间


4.2.10 TTL key

以秒为单位,返回给定key的剩余生存时间


4.2.11 RANDOMKEY

从当前数据库中随机返回一个key


4.2.12 RENAME key newkey

修改key的名称


4.2.13 RENAMENX key newkey

仅当newkey不存在时,将key改名为newkey


4.2.14 TYPE key

返回key所存储的值的类型


4.3 KV字符串命令

1、SET key value

设置键值


2、GET key

得到键值


3、GETRANGE key start end

返回key中字符串值的子字符


4、GETSET key value

将给定key的值设为value,并返回key的旧值


5、GETBIT KEY OFFSET

对key所储存的字符串值,获取指定偏移量上的位


6、MGET KEY1 KEY2

获取一个或者多个给定key的值


7、SETBIT KEY OFFSET VALUE

对key所是存储的字符串值,设置或清除指定偏移量上的位


8、SETEX key seconds value

将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。


9、SETNX key value

只有在 key 不存在时设置 key 的值。


10、SETRANGE key offset value

用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。


11、STRLEN key

返回 key 所储存的字符串值的长度。


12、MSET key value [key value ...]

同时设置一个或多个 key-value 对。


13、MSETNX key value [key value ...]

同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。


14、PSETEX key milliseconds value

这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。


15、INCR key

将 key 中储存的数字值增一。


16、INCRBY key increment

将 key 所储存的值加上给定的增量值(increment) 。


17、INCRBYFLOAT key increment

将 key 所储存的值加上给定的浮点增量值(increment) 。


18、DECR key

将 key 中储存的数字值减一。


19、DECRBY key decrement

key 所储存的值减去给定的减量值(decrement) 。


20、APPEND key value

如果 key 已经存在并且是一个字符串, APPEND 命令将 指定value 追加到改 key 原来的值(value)的末尾。


4.4 哈希命令

1、HDEL key field1 [field2]

删除一个或多个哈希表字段

2、HEXISTS key field

查看哈希表 key 中,指定的字段是否存在。

3、HGET key field

获取存储在哈希表中指定字段的值。

4、HGETALL key

获取在哈希表中指定 key 的所有字段和值

5、HINCRBY key field increment

为哈希表 key 中的指定字段的整数值加上增量 increment 。

6、HINCRBYFLOAT key field increment

为哈希表 key 中的指定字段的浮点数值加上增量 increment 。

7、HKEYS key

获取所有哈希表中的字段

8、HLEN key

获取哈希表中字段的数量

9、HMGET key field1 [field2]

获取所有给定字段的值

10、HMSET key field1 value1 [field2 value2 ]

同时将多个 field-value (域-值)对设置到哈希表 key 中。

11、HSET key field value

将哈希表 key 中的字段 field 的值设为 value 。

12、HSETNX key field value

只有在字段 field 不存在时,设置哈希表字段的值。

13、HVALS key

获取哈希表中所有值

14、HSCAN key cursor [MATCH pattern] [COUNT count]

迭代哈希表中的键值对。


4.5 列表命令

1、BLPOP key1 [key2 ] timeout

移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

2、BRPOP key1 [key2 ] timeout

移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

3、BRPOPLPUSH source destination timeout

从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

4、LINDEX key index

通过索引获取列表中的元素

5、LINSERT key BEFORE|AFTER pivot value

在列表的元素前或者后插入元素

6、LLEN key

获取列表长度

7、LPOP key

移出并获取列表的第一个元素

8、LPUSH key value1 [value2]

将一个或多个值插入到列表头部

9、LPUSHX key value

将一个值插入到已存在的列表头部

10、LRANGE key start stop

获取列表指定范围内的元素

11、LREM key count value

移除列表元素

12

以上是关于程序员怎么用好内存数据库Redis?的主要内容,如果未能解决你的问题,请参考以下文章

redis 怎么计算数据占用内存

天呐!mysql怎么启动图形化工具

面试官:Redis 内存满了怎么办?

同花顺java开发怎么样,附面试题

本地开发redis集群环境很慢怎么办

6. Redis在内存用完时会怎么办?以及Redis如何处理已过期的数据?