1、安装和配置
环境:Ubuntu16.04
sudo apt-get install redis-server #安装
redis-server #启动
redis-cli #打开客户端,此时可以执行操作了,默认没有密码。
select 0 #选择0号数据库
#客户端与Redis建立连接后会自动选择0号数据库
config set requirepass yourcode #设置密码为yourcode
quit #退出客户端
redis-cli #打开客户端
auth yourcode #输入密码,可以执行set等操作了
config get * #获取本机配置
2、常用操作
# 服务器相关
ping #测试连接是否存在
echo #打印
select 数据库编号 #选择数据库
quit #退出
dbsize #返回当前数据库中key 的个数
config get #
flushdb #删除当前数据库的所有key
flushall #删除所有数据库的所有key
info clients #查看连接情况
redis-cli -h 127.0.0.1 -p 6379 -a yourcode shutdown //停止服务
redis-server redis_6379.config //启动服务
# 键值对
set key value #设置键值对,value中没有空格时,加不加引号无影响。
get key #获取key对应的值
del key #删除键值对
keys pattern #返回所有满足正则表达式的key,注意下面的set等的名称也被当做一个key
exists key #判断一个key是否存在
expire key #设置一个key的过期时间
persist key #移除这个key的过期时间
randomkey #随机返回一个key
rename oldkey newkey #重命名key
type key #返回值类型
move key 数据库名 #把某个key移动到其它数据库
scan 0 match * count 10 #游标遍历keys
# 字符串 strings
set str1 value #设置
get str1 #不存在返回“nil”
setnx str1 value #nx表示not exist ,不存在则返回1并赋值,存在则返回0。不会覆盖已有的
setex str1 value #设置并指定str1的有效期
setrange str1 n value #把str1的下标[n,)区间替换为value
mset key1 val1 key2 val2 #批量设置,成功返回OK,失败返回0
msetnx key1 val1 key2 val2 #批量设置,所有的都不存在才会设置。成功返回OK, 失败返回0
getset key val #重新设置,并返回旧值
getrange key n1 n2 #返回key对应的val的字符子串[0,2]
mget key1 key2 #批量获取多个值
incr key #对key的val自增1,val需要是数字,返回新的值
incrby key num #key的val加上num, 返回新的值,num可以是负数
decr key #自减
dercby key num #val减去num
append key addval #给key对应的val末尾加上新的字符串,追加
strlen key #返回key的val的长度
# 哈希 hash,redis是string类型的field和value映射表
hset hash1 field0 000 #设置hash1的一个键值对,已经存在会覆盖
hget hash1 field0 #获取hash1 的field对应的值
hmset hash1 field1 "the" field2 "code" #hash1是一个hash集合,里面存储键值对
hmget hash1 field1 field2 field3 #批量获取多个field的值
hincry hash1 field va #给hash1的field1加上va
hexists field1 #测试field1在hash1 中是否存在
hlen hash1 #返回hash1中field的数量
hdel hash1 field1 #删除hash1中指定field
hkeys hash1 #返回hash1的所有field
hvals hash1 #返回hash1的所有value
hgetall hash1 #返回hash1的所有field和value
del hash1 #删除hash1
# 列表 list ,下标从零开始算
lpush list1 001 #创建并添加元素
lpush list1 002 #在头部添加元素
rpush list1 003 #在尾部添加元素
lrange list1 n1 n2 #显示[n1, n2]范围的元素, n2=-1表示到末尾
linsert list1 before 001 "004" #在指定元素之前插入
linsert list1 after 003 "005" #在指定元素之后插入
lset list1 0 "000" #把下标为0的元素设置为 000
lrem list1 n "000" #删除n个000, n=0表示全部删除
ltrim list1 0 3 #保留[0, 3]位置,其它元素删除
lpop list1 #弹出list1的头部元素,并返回被删除的元素
rpop list1 #弹出list1的尾部元素,并返回被删除元素
rpoplpush list1 list2 #弹出list1的尾部元素,并添加到list2的头部,类似的可以组合其它几种操作
lindex list1 n #返回下标n的元素
llen list1 #返回list1的长度
# 集合 set
# string 类型的无序集合,内部以哈希表实现,集合内元素不能重复
sadd set1 001 #创建并添加元素
smembers set1 #返回set1的所有元素
srem set1 001 #删除元素 001sm
spop set1 #随机返回并删除set1中的一个元素
sdiff set1 set2 #返回set1和set2的差集,set1-set2
sdiffstore set3 set1 set2 # set1-set2放入set3
sinter set1 set2 #返回所有给定集合的交集,可以多个集合
sinter set_store set1 set2 # set1,set2的交集放入set_store
sunion set1 set2 #返回所有给定集合的并集
sunionstore set_store set1 set2 #并集放入set_store
smove set1 set2 va #set1中的va元素放入set2
scard set1 #返回set1中集合的元素个数
sismember set1 va #判断va是否在set1中,返回1表示在,0 不在
srandmember set1 #随机返回set中的一个元素,不删除。注意和spop区分
# 有序集合 zset
# string类型的元素,不允许重复,关联一个score用于排序
zadd zset1 1 001 #zadd 集合名 score 元素
zrange zset1 0 -1 #返回zset1 中所有元素,按照score从小到大
zrange zset 0 -1 withscores #返回zset1中所有元素,和其score
zrevrange zset1 0 -1 #返回指定区间元素,按照score从大到小排序,可以加上withscores
zrangebyscore set1 n1 n2 #返回指定区间元素,可以加上withscores
zrem zset1 va #删除zset1 中的va元素
zincrby zset1 n va #把va的score增加n,没有va则相当于添加元素
zrank zset1 va #返回va的排名,即下标,从小到大排序
zrevrank zset1 va #返回元素排名,按照score从大到小排序
zcount zset1 n1 n2 #返回指定区间元素个数
zcard zset1 #返回集合中元素个数
zremrangebyrank zsset1 n1 n2 #删除集合中下标在区间的元素
zremrangebyscore zset1 score1 score2 #删除score在指定区间的元素
3、高级特性
3.1.安全性
设定密码之后需要用auth code 才能操作,密码要足够复杂防止暴力破解
3.2.主从复制
主从复制可以允许多个slave server拥有和master server相同的数据库副本。需要多台机器。
特点:
1、Master可以拥有多个slave。
2、多个slave可以连接同一个master外,还可以连接到其它的slave。
3、主从复制不会阻塞master, 在同步数据时,master可以继续处理client请求。
4、提高系统的伸缩性。
Redis主从复制过程:
1、Slave与master建立连接,发送sync同步命令。
2、master会启动一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存。
3、后台完在保存后,就将此文件发送给slave。
4、slave将此文件保存到硬盘上。
3.3.事务处理
原子操作。Redis只能保证一个client发起的事务中命令可以连续执行,而中间不会插入其他client的命令。
乐观锁。
multi #标记一个事物块开始,接下来的命令会放到一个队列中,不会马上执行
set age1 10
set age2 20
set age3 ha
incr age3 #这条命令会执行失败,不影响其它命令,但事务不会回滚。这与一般的理解不一样。
exe #这时会执行上面的两个命令
discard #事务回滚,清空命令队列并退出事务上下文
#乐观锁
#在第一个终端:
set age1 10
set age2 20
set name Tom
watch age1 #给age1加上乐观锁,监视age1
multi
set age1 18
#在第二个终端
set age1 25
#回到第一个终端
exec #此时返回nil,事务执行失败
get age1 #应该返回25
3.4.持久化机制
所谓持久化,是指Redis需要经常将内存中的数据同步到硬盘来保证持久化。
Redis支持两种持久化方式:
(1)snapshotting(快照) 也是默认方式。
将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
可以自定义修改配置文件redis.conf:
save 900 1 #900秒内如果超过1个key被修改,则发起快照保存。
(2)Append-only file(aof)的方式。
默认是关闭的,可以查看配置。在使用aof时,redis会将每个收到的写命令都通过write函数追加到文件中。 当然由于OS会在内核中缓存write做的修改,所以可能不是立即写到磁盘上,这样aof方式的持久化也还是有可能丢失部分修改。
3.5、发布订阅消息
发布订阅(pub/sub)是一种消息通信模式。Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向Redis Server订阅自己感兴趣的消息类型。参考
#终端1
subscribe chat1 #创建订阅频道chat,终端1用来接收信息
#终端2
publish chat "hello all" #向chat1发布消息
#终端1
punsubscribe chat1 #退订chat1
4. redis 脚本
4.1 lua脚本能够保证redis执行的原子性(当然如果lua脚本报错的话,无法回滚掉已执行的部分代码的)
4.2 shell 脚本操作redis
#shell批量写入redis
#!/bin/bash
for ((i=0;i<100;++i))
do
redis-cli -c -h 127.0.0.1 -p 6379 -a yourcode set num$i i+1000 #必须放在一行
done
5.c++操作redis
下载github的安装包,make,比较坑的地方是静态库只能用来编译,不能用来运行。所以还是需要sudo make install。
在/etc/ld.so.conf.d/目录下新建文件usr-libs.conf,内容是:/usr/local/lib
然后使用命令/sbin/ldconfig更新一下配置即可。
基本上4个接口就够用了
redisContext* redisConnect(const char *ip, int port)
//说明:该函数用来连接redis数据库,参数为数据库的ip地址和端口,一般redis数据库的端口为6379。
//类似的提供了一个函数redisContext* redisConnectWithTimeout(const char *ip, int port, timeval tv)
void *redisCommand(redisContext *c, const char *format, ...);
//说明:该函数执行redis数据库中的操作命令,第一个参数为连接数据库时返回的redisContext,剩下的参数为变参,就如C标准函数printf函数一样的变参。
//返回值为void*,一般强制转换成为redisReply*类型,以便做进行进一步的处理。
void freeReplyObject(void *reply);
// 说明:释放redisCommand执行后返回的redisReply所占用的内存
void redisFree(redisContext *c);
// 说明:释放redisConnect()所产生的连接。
#include <iostream>
#include <hiredis/hiredis.h>
int main()
{
redisContext *conn = redisConnect("127.0.0.1", 6379); //连接
if (conn != NULL && conn->err) {
printf("connection error: %s\n", conn->errstr);
return 0;
}
redisReply *reply;
reply = (redisReply*)redisCommand(conn, "auth %s", "yourcode");//输入密码
reply = (redisReply*)redisCommand(conn, "SET %s %s", "foo", "bar");//执行语句
freeReplyObject(reply); //一定要释放内存
reply =(redisReply*) redisCommand(conn, "GET %s", "foo");
printf("%s\n", reply->str); //输出
freeReplyObject(reply);
redisFree(conn);
return 0;
}
makefile:
g++ -g -o testhiredis testhiredis.cpp -L/usr/local/lib -lhiredis
当然也可以使用静态库编译,随便把静态库放哪。
脑图:转