首页 > 技术文章 > redis数据库的使用

eliwang 2021-03-25 22:30 原文

一、安装

  • 下载-----打开redis官方网站,推荐下载稳定版本(stable)

    wget https://download.redis.io/releases/redis-6.2.1.tar.gz
  • 解压

    tar -zxvf redis-6.2.1.tar.gz
  • 改名并移动到/usr/local目录下(推荐)

    sudo mv redis-6.2.1 redis
    sudo mv ./redis /usr/local/
  • 编译安装

    cd /usr/local/redis
    make && sudo make install

     

二、配置

  /usr/local/redis目录下,文件redis.conf为配置文件

  • 需要远程访问,可将此行注释:
    bind 127.0.0.1
  • 默认端口:6379,可以修改
    port 6379
  • 是否以守护进程运行
    daemonize no|yes

    如果以守护进程运行,则不会堵塞命令行,否则当前终端被阻塞,推荐设为yes

  • 数据文件名
    dbfilename dump.rdb

    数据库中添加键值后,会发现在当前运行的目录下创建了一个文件:dump.rdb,这个文件用于将数据持久化存储

  • 数据文件存储路径
    dir ./ #推荐修改为 dir /var/lib/redis/

     

三、运行

  • 修改配置文件存放目录
    sudo mkdir /etc/redis
    sudo cp /usr/local/redis/redis.conf /etc/redis/redis.conf

    一般配置文件都存放在/etc/目录下

  • 配置文件启动(方式一)
    sudo redis-server /etc/redis/redis.conf

    直接运行redis-server会阻塞当前终端

  • 后台启动服务(方式二)
    redis-server & #执行命令后,按两下回车键
  • 关闭服务
    ps -aux | grep redis
    sudo kill -9 进程号(pid)
  • 启动redis客户端
    redis-cli

     

 四、数据库以及键的命令

  • 数据库命令

    • 切换数据库
      select 数据库名 #0-15共16个数据库,默认数据库为0
    • 清空当前数据库数据
      flushdb
    • 清空所有数据库数据
      flushall
  • 键命令

    • 查找键
      keys pattern 
      keys * #查找所有
      keys n* #查找以n开头的键
    • 判断键是否存在
      exists key [key ...]

      不存在就返回0,如果判断多个,则返回存在的个数,比如判断3个键,只有2个存在,则返回2

    • 查看键对应的值类型
      type key
    • 删除键及对应的value
      del key [key ...]
    • 设置过期时间,以秒为单位
      expire key seconds

      创建时没有设置过期时间则一直存在,直到使用del移除

    • 查看有效时间,以秒为单位
      ttl key

       

五、数据操作

redis是key-value的数据,所以每个数据都是一个键值对

键的类型以及元素的类型均为字符串

值的类型可分为以下5种:

    1. 字符串string
    2. 哈希hash
    3. 列表list
    4. 集合set
    5. 有序集合zset

string

string是redis最基本的类型,是二进制安全的,即可以为任何数据,比如数字、图片、序列化对象等,最大能存储512MB数据

设置:

  • 设置键值
    set key value
  • 设置键值及过期时间,以秒为单位
    setex key seconds value
  • 设置多个键值
    mset key value [key value ...]

获取:

  • 根据键获取值,如果不存在此键则返回nil
    get key
  • 根据多个键获取多个值
    mget key [key ...]
  • 获取值长度
    strlen key

运算:(值必须是数字)

  • 键对应的值加1
    incr key
  • 值加整数
    incrby key increment
  • 值减1
    decr key
  • 值减整数
    decrby key decrement

其他:

  • 追加值
    append key value

    例如原有的键对应值是"hello",append key "world"后,值变成"helloworld"

hash

用于存储对象,对象的格式为键值对

设置:

  • 设置单个属性
    hset key field value

    注:hset现在也能设置多个属性

  • 设置多个属性
    hmset key field value [field value ...]

获取:

  • 获取单个属性的值
    hget key field
  • 获取多个属性的值
    hmget key field [field ...]
  • 获取所有属性以及值
    hgetall key
  • 获取所有属性
    hkeys key
  • 获取所有值
    hvals key 
  • 获取属性个数
    hlen key
  • 获取某个属性值的长度
    hstrlen key field

其他:

  • 判断某个属性是否存在
    hexists key field
  • 删除属性和值
    hdel key field [field ...]

list

列表的元素类型为string,在列表的头部或者尾部添加元素,按照插入顺序排序

插入:

  • 头部插入数据
    lpush key element [element ...]

    如果插入多个数据,后插入的数据会在前面,比如lpush list1 'a' 'b' 'c',结果list1中的数据顺序是'c' ,'b', 'a'

  • 头部插入数据(键不存在,则不执行命令)
    lpushx key element [element ...]
  • 尾部插入数据
    rpush key element [element ...]
  • 尾部插入数据(键不存在,则不执行命令)
    rpushx key element [element ...]
  • 在指定元素的前面或者后面插入某个元素
    linsert key BEFORE|AFTER pivot element

修改:

  • 修改指定索引的元素值,索引从0开始,也可以使用负数,-1表示最后一个
    lset key index element

获取:

  • 移除并获取第一个元素
    lpop key
  • 移除并获取最后一个元素
     rpop key
    
  • 获取指定索引对应的元素
    lindex key index
  • 获取指定索引范围内的元素
    lrange key start stop
  • 获取列表长度
    llen key  

删除

  • 根据参数count的值,移除列表中与参数element相等的元素。
    lrem key count element

    count=0,移除列表中所有相等的元素;count>0,从前向后搜索并移除count个相等的元素;count<0,从后向前搜索并移除|count|个相等的元素。

其他:

  • 裁剪列表
    ltrim key start stop

    裁剪后,成为原列表的一个子集

  • 移动某一个列表尾部数据到另一个列表头部(也可以是同一个列表)
    rpoplpush source destination

set

无序集合,元素为string类型,具有唯一性,不重复

添加:

  • 添加1个或多个元素
    sadd key member [member ...]

获取:

  • 随机返回1个或多个元素
    srandmember key [count]
  • 返回集合所有元素
    smembers key
  • 返回集合元素个数
    scard key

移除

  • 随机移除1个或多个元素,并返回被移除的元素本身
    spop key [count]

    count不指定,默认移除1个

  • 移除1个或多个元素,并返回被移除的元素个数
    srem key member [member ...]

    有则删除,没有则不做任何操作

其他:

  • 移动一个集合中的元素到另一个集合中,操作成功则返回1,否则返回0
    smove source destination member
  • 交集
    sinter key [key ...]
    

    集合共有的部分

  • 差集
    sdiff key [key ...]

    注意先后顺序,前面集合所独有的部分

  • 合集
    sunion key [key ...]
  • 判断元素是否在集合中
    sismember key member

zset

有序集合(sorted set),元素类型为string,具有唯一性,不重复,每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序,score值可以相同。

设置:

  • 添加
    zadd key score member [score member ...]

获取:

  • 获取指定索引范围内的元素
    zrange key min max
  • 获取集合元素个数
    zcard key
  • 统计权重值在某一范围内的元素个数
    zcount key min max
  • 获取某一个元素的权重值
    zscore key member
  • 随机获取一个或多个元素
    zrandmember key [count [WITHSCORES]]

     

六、发布订阅

客户端发到频道的消息,将会被推送到所有订阅此频道的客户端。

客户端不需要主动去获取消息,只需要订阅频道,这个频道的内容就会被推送过来。

  • 发布

    publish channel message
  • 订阅

     subscribe channel [channel ...]
  • 取消订阅

    unsubscribe [channel [channel ...]]

    如果不写参数,表示取消订阅所有频道

 

七、主从配置

一个主服务器可以拥有多个从服务器,一个从服务器又可以拥有多个从服务器,如此下去,形成了强大的多级服务器集群架构。

将ip为192.168.1.10的机器作为主服务器,将ip为192.168.1.11的机器作为从服务器,进行演示。

  • 主服务器配置

    bind 192.168.1.10

    修改配置文件(/etc/redis/redis.conf文件)

  • 从服务器配置

    bind 192.168.1.11
    slaveof 192.168.1.10 6379

    注意:在slaveof后面写主机ip,再写端口,而且端口必须写

  • 主服务器上写数据

    set hello world
  • 从服务器上读取数据

    get hello

     

八、与python交互

  • 安装redis包

    sudo pip3 install redis
  • 引入redis模块

    import redis
  • 创建数据库连接对象

    try:
        r = redis.StrictRedis(host='ip地址',port=6379)
    except Exception as e:
        print(e)
  • 数据库操作

    • 方式一:根据数据类型,调用相应方法

      #string类型演示
      r.set(key,value)
      r.get(key) #注意返回的是bytes类型,没有则返回None,redis中存储的数值也都是字符串类型
      
      #hash类型
      r.hset(key,field,value) #设置单个属性和值,可以执行多次
      r.hmset(key,{field1:value1,...}) #设置多个属性和值
      r.hget(key,field) #获取单个属性的值
      r.hmget(key,field1,...) #获取多个属性的值,返回的是属性的值构成的列表,bytes类型 r.hgetall(key) #获取所有属性和值,dict类型,其中的键和值都是bytes类型,例如{b'name':b'laowang',b'age':b'28'} r.expire(key,seconds) #设置过期时间 r.hdel(key,field1,...) #删除属性和值 r.delete(key) #删除键,注意是delete而不是del
    • 方式二:利用pipeline缓冲多条命令,然后一次性执行,减少服务器-客户端之间TCP数据库包,从而提高效率

      # 仅使用管道(不开启事务)
      with r.pipeline(transaction=False) as pipe:
          pipe.set('key1','value1')
          pipe.set('key2','value2')
          pipe.set('key3','value3')
          data = pipe.execute() # 返回的是一个有序列表,元素是上面每条命令执行的返回值[True,True,True]
          print(data)
      
      # 开启事务(原子性操作,要么所有命令全部执行,要么全部不执行)
      with r.pipeline() as pipe:   # transaction参数默认为True
          pipe.multi() # 开启事务
          pipe.set('key1','value1')
          pipe.set('key2','value2')
          pipe.set('key3','value3')
          data = pipe.execute() # 返回的是一个有序列表,同上
          print(data)

 

 

 

推荐阅读