Redis总结文档

标准

redis的数据类型

1、string 最简单数据类型

set name awei  / get name 设置值/取值
setnx name awei1 
    现在判断name是否存在,如果存在返回0,如果不存在设置成功
setex name 10 awei 
    设置name为awei的时间为10s
setrange name 6 gmail.com 
    设置从name值的第6个字符开始替换成gmail.com,返回字符长度
mset name1 awei1 name2 awei2 
    批量设置多个name的值,成功OK,失败返回0
msetnx name awei
    一次设置多个key的值,和setnx类似
getset name 
    设置key的值,并返回key的旧值
getrange name 0 5
    获取key的value值的子字符串
mget name name2
    一次获取多个key的值,如果对应key不存,在则对应返回nil。
incr num 
    对key的值做加加操作,并返回新的值
incrby num 4 
    同incr类似,加指定值,key不存在时候会设置key,并认为原来的value是0
decr num 
    对key的值做减减操作。 
decrby num -3 
    同decr类似,减指定值。
append name bob 
    给指定key的字符串追加value,返回新字符串值的长度。
strlen name 
    取指定key的value值的长度。

2、hash 数据类型,可以当做表 hash table 比string快

hset user:001 name awei 
    设置hash field为指定值,如果key不存在 ,则先创建。
hsetnx user:001 name awei 
    设置hash field为指定值,如果key不存在,则先创建。如果存在返回0。
hmset user:001 name awei age 20
    同时设置hash的多个field。
hget user:001 name 
    获取指定的hash field。
hmget user:001 name age 
    获取全部指定的hash field。
hincrby user:001 age 10 
    指定的hash field加上给定值。
hexists user:001 name 
    测试指定field是否存在。
hlen user:001 
    返回指定hash的field数量。
hdel user:001 age
    删除指定hash的field。
hkeys user:001 
    返回hash的所有field。
hvals user:001
    返回hash的所有value。
hgetall user:001 
    获取某个hash中全部的field及value。

3、list 数据类型 栈 队列

lrange list 0 -1
    查看所有元素
lpush list1 "hello"
    在key对应list的头部添加字符串元素。
rpush list1 "world"
    在key对应list的尾部添加字符串元素。
linsert list1 before “world” “hello”
    在key对应list的特定位置前或后添加字符
lset list1 0 “world”
    设置list中指定下标的元素值。
lrem list1 2 hello
    从key对应list中删除n个和value相同的元素。(n<0从尾删除,n=0全部删除)
ltrim list1 1 2 (1,2为键名)
    保留指定key的值范围内的数据
lpop list1
    从list的头部删除元素,并返回删除元素
rpop list1
    从list的尾部删除元素,并返回删除元素
rpoplpush list1 list2
    把一个list1尾部元素压入到list2的头部
lindex list 0
    返回名称为key的list中index位置的元素
llen list
    返回key对应list的长度

4、set 数据类型 并集 交集 差集

smembers set 
    查看set中所有元素
sadd set one
    向名称为key的set中添加元素
srem set one
    删除名称为key的set中的元素
spop set
    随机返回并删除名称为key的set中一个元素
sdiff set set2
    返回所有给定key与第一个key的差集
sdiffstore set set2 set3 (set为存储key)
    返回所有给定key与第一个key的差集,并将结果存为另一个key
sinter set set2
    返回所有给定key的交集
sinterstore set set2 set3 (set为存储key)
    返回所有给定key的交集,并将结果存为另一个key
sunion set set2
    返回所有给定key的并集 
sunionstore set set2 set3 (set为存储key)
    返回所有给定key的并集
smove set3 set2 1
    从第一个key对应的set中移除member并添加到第二个对应的set中 
scard set
    返回名称为key的set的元素个数
sismember set 1
    测试member是否是名称为key的set的元素
srandmember set
    随机返回名称为key的set的一个元素,但不删除元素

5、zset set的升级版,多一个顺序

zrange set 0 -1 (zrange set 0 -1 withscores 会显示序列号)
    按升序查看所有元素
zrevrange set 0 -1 (zrevrangeset 0 -1 withscores 会显示序列号 )
    按降序查看所有元素
zrangebyscore myzset3 2 3 withscores
   返回集合中score在给定区间的元素
zadd set 1 one
    向名称为key的zset中添加元素member,score用于排序。如果该元素存在,则更新其顺序
zrem set one
    删除名称为key的zset中的元素member
zincrby set 3 one
    如果在名称为key的zset中已经存在元素member,则该元素的score增加increment,否则向该集合中添加该元素,其score的值为increment
zrank set one 
    返回名称为key的zset中member的元素排序(按score从小到大排序)即下标
zrevrank set one
    返回名称为key的zset中member的元素排序(按score从大到小排序)即下标
zcount set 2 3
    返回集合中score在给定区间的数量
zcard set
    返回集合set所有元素个数
zremrangebyrank set 1 2
    删除集合中排名在给定区间中的元素
zremrangebyscore set 1 2 
    删除集合中score在给定区间中的元素

redis的高级应用

1、安全性

在配置文件redis.conf中设置客户端连接后进行任何其他指令前需要使用的密码。requirepass beijing我们设置了连接的口令是beijing

我们启动一个客户端试一下。

[root@localhost redis-2.2.12]# src/redis-cli
redis 127.0.0.1:6379> keys *
(error) ERR operation not permitted
redis 127.0.0.1:6379>
这里显示权限被禁止,我们来设置一下权限
redis 127.0.0.1:6379> auth beijing
OK
redis 127.0.0.1:6379> keys *
1) "name"
redis 127.0.0.1:6379>

我们还可以在连接到服务器期间就指定一个口令

[root@localhost redis-2.2.12]# src/redis-cli -a beijing
redis 127.0.0.1:6379> keys *
1) "name"
redis 127.0.0.1:6379>

2、主从复制

Redis主从复制配置和使用都非常简单。通过主从 复制可以允许多个slave server拥有和master server相同的数据库副本。

Redis主从复制特点:

1.Master可以拥有多个slave
2.多个slave可以连接同一个master外,还可以连接到其它slave
3.主从复制不会阻塞master,在同步数据时,master可以继续处理client请求
4.提高系统的伸缩性

Redis主从复制过程:

1.Slave与master建立连接,发送sync同步命令
2.Master会启动一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存。
3.后台完成保存后,就将此文件发送给slave
4.Slave将此文件保存到硬盘上

配置主从服务器:

配置slave服务器很简单,只需要在slave的配置文件中加入以下配置:
slaveof 192.168.1.1 6379 #指定master 的ip 和端口
masterauth awei#这是主机的密码
设置成功后,我们来做一个实验:
我们在主数据库上设置一对键值对
redis 127.0.0.1:6379> set name master
OK
redis 127.0.0.1:6379>
在从数据库上取这个键
redis 127.0.0.1:6378> get name
“master"
redis 127.0.0.1:6378>
那我们怎么判断哪个是主哪个是从呢?我们只需调 用info就可以得到主从的信息,我们在从库中执行
redinisf o12 7.0.0.1:6378> info
role:slave
master_host:localhost
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
db0:keys=1,expires=0
redis 127.0.0.1:6378>

3、事务(简单事务处理)

Redis对事务的支持目前还比较简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,而间不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。

简单事务处理
redis 127.0.0.1:6379> get age
"33"
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> set age 10
QUEUED
redis 127.0.0.1:6379> set age 20
QUEUED
redis 127.0.0.1:6379> exec
1) OK
2) OK
redis 127.0.0.1:6379> get age
"20"
redis 127.0.0.1:6379>
如何取消一个事务
redis 127.0.0.1:6379> get age
"20"
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> set age 30
QUEUED
redis 127.0.0.1:6379> set age 40
QUEUED
redis 127.0.0.1:6379> discard
OK
redis 127.0.0.1:6379> get age
"20"
redis 127.0.0.1:6379>

可以发现这次2 个set age 命令都没被执行。discard 命令其实就是清空事务的命令队列并退出事务上下文,也就是我们常说的事务回滚。

乐观锁复杂事务控制

乐观锁:大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表添加一个”version”字段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号加1。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行比对,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。

Redis乐观锁实例:假设有一个age的key,我们开2个 session来对age进行赋值操作,我们来看一下结果如何。

1)第1 步 session1 
127.0.0.1:6379> get age
"10"
127.0.0.1:6379> watch age
OK
127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379>
2)第2 步 session2 
redis 127.0.0.1:6379> set age 30
OK
redis 127.0.0.1:6379> get age
"30"
redis 127.0.0.1:6379>
3)第3步 session1 
redis 127.0.0.1:6379>set age 20
QUEUED
redis 127.0.0.1:6379>exec
(nil)
redis 127.0.0.1:6379>get age
"30"
redis 127.0.0.1:6379>

watch 命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失 败。也可以调用watch多次监视多个key.这样就可以对指定的key加乐观锁了。注意watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。当然了exec,discard,unwatch命令都会清除连接中的所有监视。

事务回滚(还不完善)
redis 127.0.0.1:6379> get age
"30"
redis 127.0.0.1:6379> get name
“lijie"
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr age
QUEUED
redis 127.0.0.1:6379> incr name
QUEUED
redis 127.0.0.1:6379> exec
1) (integer) 31
2) (error) ERR value is not an integer or out of range
redis 127.0.0.1:6379> get age
"31"
redis 127.0.0.1:6379> get name
“lijie"
redis 127.0.0.1:6379>

从这个例子中可以看到,age 由于是个数字,那么它可以有自增运算,但是name 是个字符串,无法对其进行自增运算,所以会报错,如果按传统关系型数据库的思路来讲,整个事务都会回滚,但是我们看到redis 却是将可以执行的命令提交了,所以这个现象对于习惯于关系型数据库操作的朋友来说是很别扭的,这一点也是redis 今天需要改进的地方。

4、持久化机制

Redis是一个支持持久化的内存数据库,也就是说redis 需要经常将内存中的数据同步到硬盘来保证持久化。

Redis支持两种持久化方式:

1.snapshotting(快照)也是默认方式
2.Append-only file(缩写aof)的方式。

Snapshotting方式

快照是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key呗修改就自动做快照。

save 900 1 #900秒内如果超过1个key被修改,则发起快照保存
save 300 10 #300秒内容如超过10个key被修改,则发起快照保存
save 60 10000

aof方式

由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。 aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。 当然由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。可以通过配置文件告诉redis我们想要通过fsync函数强制os写入到磁盘的时机。

appendonly yes //启用aof 持久化方式

# appendfsync always //收到写命令就立即写入磁盘,最慢,但是保证完全的 持久化 
appendfsync everysec //每秒钟写入磁盘一次,在性能和持久化方面做了很好 的折中 
# appendfsync no //完全依赖os,性能最好,持久化没保证

5、发布及订阅消息

发布订阅(pub/sub)是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将信息类型称为通道(channel)。当发布者通过publish命令向redis server发送特定类型的信息时,订阅该信息类型的全部client都会收到此消息。

客户端1 
127.0.0.1:6379> subscribe tv1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "tv1"
3) (integer) 1
客户端2
127.0.0.1:6379> publish tv1 awei
(integer) 1
127.0.0.1:6379>
客户端1
1) "message"
2) "tv1"
3) "awei"

6、虚拟内存的使用(redis2.4后已经不适用了)

Redis的虚拟内存与操作系统的虚拟内存不是一回事,但是思路和目的都是相同的。就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用于其他需要访问的数据。尤其是对于redis这样的内存数据库,内存总是不够用的。除了可以将数据分割到多个redis server外。另外能够提高数据库容量的办法就是使用虚拟内存把那些不经常访问的数据交换到磁盘上。

下面是vm相关配置:

vm-enabled yes #开启vm功能
vm-swap-file /tmp/redis.swap #交换出来的value保存的文件路径
vm-max-memory 1000000 #redis使用的最大内存上限
vm-page-size 32 #每个页面的大小32字节
vm-pages 134217728 #最多使用多少页面
vm-max-threads 4 #用于执行value对象换入患处的工作线程数量

redis的常用命令

1、键值相关命令

keys * 
    返回满足给定pattern的所有key
exists list1
    确认一个key是否存在
del list1
    删除一个key
expire addr 10
    设置一个key的过期时间redis
127.0.0.1:6379> ttl addr
(integer) 8
redis 127.0.0.1:6379> ttl addr
(integer) 1
redis 127.0.0.1:6379> ttl addr
(integer) -1
redis 127.0.0.1:6379>
    在本例中,我们设置addr 这个key 的过期时间是10 秒,然后我们不断的用ttl 来获取这个key 的有效时长,至为-1 说明此值已过

persist set
    移除给定key的过期时间
 
move age 1 (redis有0—15个数据库,默认是0数据库)
    将当前数据库中的key转移到其它数据库中 
redis 127.0.0.1:6379> select 0
OK
redis 127.0.0.1:6379> set age 30
OK
redis 127.0.0.1:6379> get age
"30"
redis 127.0.0.1:6379> move age 1
(integer) 1
redis 127.0.0.1:6379> get age
(nil)
redis 127.0.0.1:6379> select 1
OK
redis 127.0.0.1:6379[1]> get age
"30"
randomkey
    随机返回key空间的一个key
rename set set2
    重命名key
type set
    返回值的类型

2、服务器相关命令

ping
    测试连接是否存活
echo awei
    在命令行打印一些内容
select 15
    选择数据库。Redis数据库编号从0~15,我们可以
选择任意一个数据库来进行数据的存取
quit
    退出连接。
dbsize
    返回当前数据库中key的数目。
info
    显示系统信息
config get dir
    实时传储收到的请求。
redis 127.0.0.1:6379> config get dir
1) "dir"
2) "/root/4setup/redis-2.2.12"
redis 127.0.0.1:6379>
    本例中我们获取了dir 这个参数配置的值,如果想获取全部参数据的配置值也很简单,只需要执行”config get *”即可将全部的值都显示出来。
 
flushdb
    删除当前选择数据库中的所有key。
flushall
    删除所有数据库中的所有key。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

53 − 51 =