redis学习

概述

  • redis:REmote DIctionary Server是一种nosql数据库,它的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,并且它比memcached支持更多的数据结构(string,list列表[队列和栈],set[集合],sorted set[有序集合],hash(hash表))
  • 更多命令可以查看REDIS文档

安装

  • kali: apt-get install redis-server
  • 启动: service redis-server start
  • 查看: ps aux|grep redis

操作

  • 连接:redis-cli -h[ip] -p[port]

    字符串操作

  • 添加:

    1
    2
    3
    4
    set key value
    set username chenxiyuan
    set website "chenxiyuan.vip"
    # 默认过期时间永久。如果ket已经有其他值,则直接覆盖,无视其类型
  • 删除: del key

  • 设置过期时间:

    1
    2
    3
    4
    expire key seconds
    # 也可以在设置值得时候指定
    set key value EX seconds
    setex key seco value
  • 查看过期时间:ttl key

  • 查看所有的key:keys *

    列表操作

  • 在列表左边添加元素:即插入表头

    1
    lpush key value
  • 在列表右边添加元素:即插入表尾

    1
    rpush key value
  • 查看列表中的元素:

    1
    2
    3
    lrange key start stop
    #查看所有元素
    lrange key 0 -1
  • 移除列表中的元素:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #移除并返回列表的头元素
    lpop key
    #移除并返回列表的尾元素
    rpop key
    #移除并返回列表的中间元素
    lrem key count value
    #count>0:删除从表头开始的count个value
    #count<0:删除从表尾开始的|count|个value
    #count=0:删除表中所有的value
  • 指定返回第几个元素:

    1
    lindex key index
  • 获取列表的长度:llen key

    set集合操作:

  • 添加元素:

    1
    2
    sadd key member [member ...]
    sadd students xiaohong xiaoming
  • 查看集合中的元素:

    1
    smembers key
  • 查看集合中元素个数:

    1
    scard key
  • 移除元素:

    1
    srem key member [member ...]
  • 获取多个集合的交集:

    1
    2
    3
    4
    5
    sinter key [key ...]
    # sadd class1 xiaohong xiaobai xiaoming
    # sadd class2 xiaobai xiaole xiaohong xiaotian
    # sinter class1 class2
    # 1) "xiaobai" 2) "xiaohong"
  • 获取多个集合的并集:

    1
    sunion key [key ...]
  • 获取多个集合的差集:

    1
    2
    3
    4
    5
    6
    sdiff key [key ...]
    # sdiff class1 class2
    # 1) "xiaoming"
    # sdiff class2 class1
    # 1) "xiaole"
    # 2) "xiaotian"

hash哈希操作:

  • 添加一个新值:

    1
    2
    hset key field value
    #hset blog chenxiyuan chenxiyuan.vip
  • 获取hash中的field对应的value:

    1
    hget key field
  • 删除field:

    1
    hdel key field [field ...]
  • 获取hash中的所有field和value:

    1
    hgetall key
  • 获取hash中所有键:

    1
    hkeys key
  • 获取hash中所有值:

    1
    hvals key
  • 获取hash键值对数量:

    1
    hlen key

事务

  • multi: 标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。
  • exec: 执行所有事务块内的命令。假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么 EXEC 命令只在这个(或这些) key 没有被其他命令所改动的情况下执行并生效,否则该事务被打断(abort)。
  • discard: 取消事务,放弃执行事务块内的所有命令。
    如果正在使用 WATCH 命令监视某个(或某些) key,那么取消所有监视,等同于执行命令 UNWATCH 。
  • watch: 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
  • unwatch: 取消 WATCH 命令对所有 key 的监视。
    如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行 UNWATCH 了。
    因为 EXEC 命令会执行事务,因此 WATCH 命令的效果已经产生了;而 DISCARD 命令在取消事务的同时也会取消所有对 key 的监视,因此这两个命令执行之后,就没有必要执行 UNWATCH 了。

发布和订阅操作

  1. 我用的是kali,然后再用xshell连接kali虚拟机,也用redis-cli连接上。
    注:用xshell连接kali,需要执行以下操作
    1
    vim /etc/ssh/sshd_config


1
2
3
4
5
6
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

修改为

1
2
3
4
5
6
# Authentication:
LoginGraceTime 2m
PermitRootLogin yes
StrictModes yes
MaxAuthTries 6
MaxSessions 10

重启ssh服务

1
service ssh restart

设置ssh服务开机自启动

1
update-rc.d ssh enable

  1. kali虚拟机订阅频道

    1
    2
    #subscribe channel [channel ...]
    subscribe chatroom
  2. xshell发布一个消息

    1
    #publish channel message

持久化

  • redis提供了两种数据备份方式,一种是RDB,另外一种是AOF:
RDB AOF
开启关闭 开启:默认开启。关闭:把配置文件中所有的save都注释,就是关闭了。 开启:在配置文件中appendonly yes即开启了aof,为no关闭。
同步机制 可以指定某个时间内发生多少个命令进行同步。比如1分钟内发生了2次命令,就做一次同步。 每秒同步或者每次发生命令后同步
存储内容 存储的是redis里面的具体的值 存储的是执行的更新数据的操作命令
存储文件的路径 根据dir以及dbfilename来指定路径和具体的文件名 根据dir以及appendfilename来指定具体的路径和文件名
优点 (1)存储数据到文件中会进行压缩,文件体积比aof小。(2)因为存储的是redis具体的值,并且会经过压缩,因此在恢复的时候速度比AOF快。(3)非常适用于备份。 (1)AOF的策略是每秒钟或者每次发生写操作的时候都会同步,因此即使服务器故障,最多只会丢失1秒的数据。 (2)AOF存储的是Redis命令,并且是直接追加到aof文件后面,因此每次备份的时候只要添加新的数据进去就可以了。(3)如果AOF文件比较大了,那么Redis会进行重写,只保留最小的命令集合。
缺点 (1)RDB在多少时间内发生了多少写操作的时候就会出发同步机制,因为采用压缩机制,RDB在同步的时候都重新保存整个Redis中的数据,因此你一般会设置在最少5分钟才保存一次数据。在这种情况下,一旦服务器故障,会造成5分钟的数据丢失。(2)在数据保存进RDB的时候,Redis会fork出一个子进程用来同步,在数据量比较大的时候,可能会非常耗时。 (1)AOF文件因为没有压缩,因此体积比RDB大。 (2)AOF是在每秒或者每次写操作都进行备份,因此如果并发量比较大,效率可能有点慢。(3)AOF文件因为存储的是命令,因此在灾难恢复的时候Redis会重新运行AOF中的命令,速度不及RDB。
更多 http://redisdoc.com/topic/persistence.html#redis

客户端与服务器

设置密码

  1. 设置临时密码
    redis连接后,输入命令CONFIG SET requirepass password可以使用密码来保护 Redis 服务器。示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    127.0.0.1:6379> config set requirepass secret_password
    OK
    127.0.0.1:6379> quit #重新启动,以生效
    root@chenxiyuan:/etc/redis# redis-cli -h 127.0.0.1 -p 6379
    127.0.0.1:6379> ping
    (error) NOAUTH Authentication required. #未验证密码,操作被拒绝
    127.0.0.1:6379> auth secret_password
    OK
    127.0.0.1:6379> ping #验证密码后,成功执行
    PONG
  2. 设置永久密码
    配置文件/etc/redis/redis.conf,打开配置文件找到SECURITY部分,添加

    1
    requirepass yourpassword

重新启动服务即可

其他机器连接本机redis

这里我又开了一台ubuntu:192.168.91.134

1
2
3
4
vim /etc/redis/redis.conf 
#注释掉 bind 127.0.0.1 那行,再重启服务
#或者bind 127.0.0.1 192.168.91.134 注意这里是ubuntu的ip地址,如果填的是kali的,则redis服务根本起不来。
sudo service redis-server restart

然后kali:192.168.91.133连接

1
2
3
4
5
6
7
8
redis-cli -p 6379 -h 192.168.91.134
192.168.91.134:6379> ping
(error) NOAUTH Authentication required.
192.168.91.134:6379> auth chenxiyuan
OK
192.168.91.134:6379> ping
PONG
# 成功,ubunturedis服务器一定要设置密码,不然会有protected mode 默认是开的,会拒绝访问。

python操作redis

安装redis

1
2
3
pip install redis
#因为我的kali有两个版本的python,而默认是python2,所以我这样安装
python3 -m pip install redis

连接redis

因为python操作redis的方法与redis-cli操作方法基本类似,就不赘述了。

1
2
3
4
5
6
>>> from redis import Redis
>>> cache=Redis(host='127.0.0.1',port=6379,password='chenxiyuan')
>>> cache.set('username','chenxiyuan')
True
>>> cache.get('username')
b'chenxiyuan'

事务操作

1
2
3
4
5
6
7
8
# 定义一个管道实例
pip = cache.pipeline()
# 做第一步操作,给BankA自增长1
pip.incr('BankA')
# 做第二步操作,给BankB自减少1
pip.desc('BankB')
# 执行事务
pip.execute()

主从复制

建立

ubuntu:192.168.91.134

1
2
3
127.0.0.1:6379> info replication
# Replication
role:master

kali:192.168.91.133

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
127.0.0.1:6379> slaveof 192.168.91.134 6379
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.91.134
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:195
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:589b79b1011b3c7e933cefc0fb4a8ae8190696b9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:195
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:114
repl_backlog_histlen:82

读写分离

从机是无法写的

1
2
127.0.0.1:6379> set username chenxiyuan
(error) READONLY You can't write against a read only replica.

主机死掉

ubuntu: shutdown
kali: 还是slave,当主机重新连入写数据,从机还是可以读数据。

从机死掉

kali: shutdown,重新连入后为master,除非写入配置。只要再slaveof,还是可以读到主机的所有数据

反客为主

1
slaveof no one