redis

作者: 全村滴希望 | 来源:发表于2020-05-15 22:08 被阅读0次

    redis安装与配置

    1. 获取redis资源

      wget http://download.redis.io/redis-stable.tar.gz 
      
    2. 解压

      tar -xzvf redis-stable.tar.gz
      
    3. 安装

      cd redis-stable
      make
      cd src
      make install PREFIX=/usr/local/redis
      

      make报错:

      MAKE hiredis
      cd hiredis && make static 
      make[3]: Entering directory `/root/redis-stable/deps/hiredis'
      cc -std=c99 -pedantic -c -O3 -fPIC   -Wall -W -Wstrict-prototypes -Wwrite-strings -Wno-missing-field-initializers -g -ggdb net.c
      make[3]: cc: Command not found
      make[3]: *** [net.o] Error 127
      make[3]: Leaving directory `/root/redis-stable/deps/hiredis'
      make[2]: *** [hiredis] Error 2
      make[2]: Leaving directory `/root/redis-stable/deps'
      make[1]: [persist-settings] Error 2 (ignored)
          CC adlist.o
      /bin/sh: cc: command not found
      make[1]: *** [adlist.o] Error 127
      make[1]: Leaving directory `/root/redis-stable/src'
      make: *** [all] Error 2
      

    解决办法:安装gcc

    yum install -y gcc
    

    make报错:

    zmalloc.h:50:31: error: jemalloc/jemalloc.h: No such file or directory
    zmalloc.h:55:2: error: #error "Newer version of jemalloc required"
    make[1]: *** [adlist.o] Error 1
    make[1]: Leaving directory `/data0/src/redis-2.6.2/src'
    make: *** [all] Error 2
    

    原因是jemalloc重载了Linux下的ANSI C的malloc和free函数。解决办法:make时添加参数。

    make MALLOC=libc
    

    报错:

    serverLog(LL_NOTICE,"The server is now ready to accept connections at %s", server.unixsocket);
                                                                                                  ^
    server.c:5103:19: error: ‘struct redisServer’ has no member named ‘supervised_mode’
             if (server.supervised_mode == SUPERVISED_SYSTEMD) {
                       ^
    server.c:5104:24: error: ‘struct redisServer’ has no member named ‘masterhost’
                 if (!server.masterhost) {
                            ^
    server.c:5117:15: error: ‘struct redisServer’ has no member named ‘maxmemory’
         if (server.maxmemory > 0 && server.maxmemory < 1024*1024) {
                   ^
    server.c:5117:39: error: ‘struct redisServer’ has no member named ‘maxmemory’
         if (server.maxmemory > 0 && server.maxmemory < 1024*1024) {
                                           ^
    server.c:5118:176: error: ‘struct redisServer’ has no member named ‘maxmemory’
             serverLog(LL_WARNING,"WARNING: You specified a maxmemory value that is less than 1MB (current value is %llu bytes). Are you sure this is what you really want?", server.maxmemory);
                                                                                                                                                                                    ^
    server.c: In function ‘hasActiveChildProcess’:
    server.c:1476:1: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
    server.c: In function ‘allPersistenceDisabled’:
    server.c:1482:1: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
    server.c: In function ‘writeCommandsDeniedByDiskError’:
    server.c:3747:1: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
    server.c: In function ‘iAmMaster’:
    server.c:4914:1: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
    make[1]: *** [server.o] Error 1
    make[1]: Leaving directory `/usr/src/redis-6.0.1/src'
    make: *** [install] Error 2
    

    解决办法:

    # 查看gcc版本是否在5.3以上,centos7.6默认安装4.8.5
    gcc -v
    # 升级gcc到5.3及以上,如下:
    升级到gcc 9.3:
    yum -y install centos-release-scl
    yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
    scl enable devtoolset-9 bash
    需要注意的是scl命令启用只是临时的,退出shell或重启就会恢复原系统gcc版本。
    如果要长期使用gcc 9.3的话:
     
    echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
    这样退出shell重新打开就是新版的gcc了
    以下其他版本同理,修改devtoolset版本号即可。
    

    安装好后进行

    make test
    

    报错 :You need tcl 8.5 or newer in order to run the Redis test

    解决办法:安装tcl

    wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz  
    sudo tar xzvf tcl8.6.1-src.tar.gz  -C /usr/local/  
    cd  /usr/local/tcl8.6.1/unix/  
    sudo ./configure  
    sudo make  
    sudo make install   
    
    1. 移动配置文件到安装目录下

      cd ../
      mkdir /usr/local/redis/etc
      cp redis.conf /usr/local/redis/etc
      
    2. 配日志redis为后台启动,并修改存储路径

      vi /usr/local/redis/etc/redis.conf 
      #将daemonize no 改为
      daemonize yes
      #数据文件
      dbfilename dump.rdb
      #数据文件存储路径 默认为dir ./  提前创建/var/lib/redis文件夹
      dir /var/lib/redis
      #日志文件 提前创建/var/log/redis/目录
      logfile "/var/log/redis/redis-server.log"
      #数据库,默认有16个
      database 16
      #主从复制,类似于双机备份
      slaveof
      
    3. 将redis加入到开机启动

      vi /etc/rc.local //在里面添加内容:/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf (意思就是开机调用这段开启redis的命令)
      
    4. 将redis加入centos的systemctl服务

      cd /usr/lib/systemd/system
      vim redis.service
      
      [Unit]
      Description=Redis Server
      After=network.target
      
      [Service]
      # pid文件和redis配置设置的pid一致
      PIDFile=/var/run/redis_6379.pid
      # redis-server路径和配置文件
      ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
      # redis-cli
      # ExecStop=/usr/local/redis/bin/redis-cli -a password shutdown
      ExecStop=/bin/kill -s QUIT $MAINPID
      ExecReload=/bin/kill -s HUP $MAINPID
      
      [Install]
      WantedBy=mutli-user.target
      
      systemctl enable redis.service  //加入开机启动,先执行这个
      systemctl start redis //开启redis服务
      systemctl status redis  //查看redis运行状态
      
    1. 添加环境变量

      vim ~/.bashrc
      export PATH=$PATH:/usr/local/redis/bin
      source ~/.bashrc
      
    2. 开启redis服务端

      /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf 
      
    3. 常用命令

    redis-server /usr/local/redis/etc/redis.conf //启动redis
    pkill redis  //停止redis
    # 卸载redis:
    rm -rf /usr/local/redis //删除安装目录
    rm -rf /usr/bin/redis-* //删除所有redis相关命令脚本
    m -rf /root/download/redis-4.0.4 //删除redis解压文件夹
    
    1. 开启redis客户端

      #连接rediscil +端口号 默认127.0.0.1
      redis-cli
      
      #切换数据库
      #数据库有名称,默认有16个,通过0-15来标识,连接redis默认选择第一个数据库
      select n
      

    redis 数据操作

    redis命令参考文档
    redis.py参考文档

    redis是key-value的数据结构,每条数据都是一个键值对

    键的类型是字符串,键不能重复。

    值得类型分为五种:String、hash、list、set(集合)、zset(有序集合)

    1. String

      redis重字符串类型的value最多可以容纳得数据长度是512M。

    如果设置的键不存在则为添加,如果设置的键已经存在则为修改。

    set key value
    

    设置键值及过期时间,以秒为单位

    setex key seconds value
    

    设置多个键值

    mset key1 value1 key2 value2 ...
    

    追加值

    append key value
    
    

    根据键获取值,如果不存在此键则返回nil

    get key
    

    根据多个键获取多个值

    megt key1 key2 key3
    
    1. 键命令

      查找键,参数支持正则表达式

      keys pattern
      # keys * 查找所有键
      # keys a* 查看名称中包含a的键
      

      判断键是否存在,如果存在返回1,不存在返回0

      exists key
      

      查看键的类型

      type key
      

      删除键及对应的值

      del key1 key2 ...
      

      设置过期时间,以秒为单位

      如果没有指定过期时间则一直存在,知道使用DEL移除

      expire key seconds
      

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

      ttl key
      
    1. hash

      hash用于存储对象,对象的结构为属性、值,值的类型为string

      设置单个属性

      hset key field value
      # hset user name haha 设置user键的值为 name属性对应值为haha
      

      如果redis被配置为保存数据库快照,但它不能持久化到硬盘。用来修改集合数据的命令不能用

      运行 config set stop-writes-on-bgsave-error no 命令狗,关闭快照。

      设置多个属性

      hmset key field1 value1 field2 value2 field3 value3...
      

    获取键值

    hget key field
    

    获取多个属性的值

    hegt key field1 field2
    

    获取所有属性的值

    hvals key
    

    删除整个hash键及值,使用del命令

    删除属性,属性对应的值会被一起删除

    hdel key field1 field2...
    
    1. list

      列表的元素类型为string,按照插入顺序排序

      在左侧插入数据

      lpush key value1 value2 ...
      

      在右侧插入数据

      rpush key value1 value2 ...
      

      在指定元素的前面和后面插入数据

      linsert key before/after new old
      # 在键为 a1 的列表中元素 b 前插入 3
      # linsert a1 before b 3
      

    返回列表里指定范围内的元素

    start、stop为元素的下标索引

    索引从左侧开始,第一个元素为0

    索引可以是负数,表示从尾部开始计数,如-1表示最后一个元素

    lrange key start stop
    # 查看a1的所有元素
    # lrange a1 0 -1
    

    设置指定索引位置的元素值

    索引从左侧开始,第一个元素为9

    所以可以是负数,表示尾部开始计数,如-1表示最后一个元素

    lset key index value
    

    删除指定元素

    将列表中前count次出现的值为value的元素移除

    count > 0: 从头向尾移除

    count < 0: 从尾向头移除

    count = 0: 移除所有

    lrem key count value
    
    1. set

      无序集合、元素为string类型,元素具有唯一性,不重复、对于集合没有修改操作

      添加元素

      sadd key member1 member2
      # sadd a3 zhangsan lisi wangwu
      

    返回所有的元素

    smembers key
    

    删除指定的元素

    srem key value
    
    1. zset

      有序集合、元素为string类型,元素具有唯一性,不重复、对于集合没有修改操作

      每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序

      添加元素

      zadd key score1 member1 score2 member2 ...
      # 向键a4的集合重添加元素 zhangsan lisi wangwu, 权重分别为3 4 5
      # zadd a4 3 zhangsan 4 lisi 5 wangwu
      

    返回指定范围内的元素

    start、stop为元素的下标索引

    索引从左侧开始,第一个元素为0

    索引可以是负数,表示从尾部开始计数,如-1表示最后一个元素

    zrange key start stop
    

    返回score值在min和max之间的成员

    zrangebyscore key min max
    # min 和 max 包括在内
    

    返回成员member的score值

    zscore key member
    

    删除指定元素

    zrem key member1 member2 ...
    

    删除权重在指定范围的元素

    zremrangebyscore key min max
    # min 和 max 包括在内
    

    搭建主从

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

    master用来写数据,slave用来读数据,经统计:网站的读写比率是10:1

    通过主从配置可以实现读写分离

    主从可以是不同的服务器,也可以在同一台服务器,在同一台服务器时,端口号要设置不一样

    1. 在主服务节点上,修改etc/redis/redis.conf文件

      vi redis.conf
      bind 192.168.220.132
      
    2. 重启redis服务

      systemctl restart redis
      # 同一台服务器上需要启动不同的配置文件
      systemctl stop redis
      redis-server /usr/local/redis/etc/redis.conf
      
    1. 在从服务节点上,修改etc/redis/slave.conf文件(内容可以从主服务复制)

      vi slave.conf
      bind 192.168.220.133
      slaveof 192.168.220.132 6379
      port 6379 # 同一台服务器上需要绑定不同的端口
      
    2. 启动redis服务

      redis-server /usr/local/redis/etc/slave.conf
      
    3. 查看主从关系

      redis-cli -h 192.168.220.132 -p 6379 info Replication
      

    搭建集群

    192.168.220.132
    192.168.220.133
    

    redis集群搭建

    Python搭建redis集群

    1. 配置服务器1 (192.168.220.132)

    在/usr/local/redis/etc/conf/目录下创建三个文件分别为7000.conf、7001.conf、7002.conf

    port 7000
    bind 192.168.220.132
    daemonize yes
    pidfile 7000.pid
    cluster-enabled yes
    cluster-config-file 7000_node.conf
    cluster-node-timeout 15000
    appendonly yes
    
    port 7001
    bind 192.168.220.132
    daemonize yes
    pidfile 7001.pid
    cluster-enabled yes
    cluster-config-file 7001_node.conf
    cluster-node-timeout 15000
    appendonly yes
    
    port 7002
    bind 192.168.220.132
    daemonize yes
    pidfile 7002.pid
    cluster-enabled yes
    cluster-config-file 7002_node.conf
    cluster-node-timeout 15000
    appendonly yes
    

    使用配置文件启动redis服务

    redis-server /usr/local/redis/etc/conf/7000.conf
    redis-server /usr/local/redis/etc/conf/7001.conf
    redis-server /usr/local/redis/etc/conf/7002.conf
    
    1. 配置服务器2(192.168.220.133)

    在/usr/local/redis/etc/conf/目录下创建三个文件分别为7003.conf、7004.conf、7005.conf

    port 7003
    bind 192.168.220.133
    daemonize yes
    pidfile 7003.pid
    cluster-enabled yes
    cluster-config-file 7003_node.conf
    cluster-node-timeout 15000
    appendonly yes
    
    port 7004
    bind 192.168.220.133
    daemonize yes
    pidfile 7004.pid
    cluster-enabled yes
    cluster-config-file 7004_node.conf
    cluster-node-timeout 15000
    appendonly yes
    
    port 7005
    bind 192.168.220.133
    daemonize yes
    pidfile 7005.pid
    cluster-enabled yes
    cluster-config-file 7005_node.conf
    cluster-node-timeout 15000
    appendonly yes
    

    使用配置文件启动redis服务

    redis-server /usr/local/redis/etc/conf/7003.conf
    redis-server /usr/local/redis/etc/conf/7004.conf
    redis-server /usr/local/redis/etc/conf/7005.conf
    
    1. 创建集群

      redis的安装包重包含了redis-trib.rb, 用于创建集群

      在192.168.220.132机器上进行,找到redis源码安装包

      cp redis-stable/src/redis-trib.rb /usr/local/redis/bin
      

      安装ruby环境,因为redis-trib.rb是用ruby开发的

      yum install -y ruby
      

    redis5.0使用redis-cli作为创建集群的命令,使用c语言实现,不再使用ruby语言。
    因此无需使用 redis-trib.rb 文件,直接使用redis-cli

    创建集群

    redis-trib.rb create --replicas 1 192.168.220.132:7000 192.168.220.132:7001 192.168.220.133:7002 192.168.220.133:7003 192.168.220.134:7004 192.168.220.134:7005
    redis-cli --cluster create  192.168.220.132:7000 192.168.220.132:7001 192.168.220.133:7002 192.168.220.133:7003 192.168.220.134:7004 192.168.220.134:7005  --cluster-replicas 1
    
    >>> Performing hash slots allocation on 6 nodes...
    Master[0] -> Slots 0 - 5460
    Master[1] -> Slots 5461 - 10922
    Master[2] -> Slots 10923 - 16383
    Adding replica 192.168.220.133:7003 to 192.168.220.132:7000
    Adding replica 192.168.220.134:7005 to 192.168.220.133:7002
    Adding replica 192.168.220.132:7001 to 192.168.220.134:7004
    M: cb6d97578ad557a6ab5acfd5a49f8ee1cf10d53e 192.168.220.132:7000
       slots:[0-5460] (5461 slots) master
    S: ccc9f32340c96ef86e38728f2c5f1a690301273f 192.168.220.132:7001
       replicates e841619eaf26e340a3e707295a0abf59feb6a469
    M: c30c612e164c9203f4a2efb1dc63c951572ad417 192.168.220.133:7002
       slots:[5461-10922] (5462 slots) master
    S: 944e29825311f57384e93dcedd153b5bbf0e9ddc 192.168.220.133:7003
       replicates cb6d97578ad557a6ab5acfd5a49f8ee1cf10d53e
    M: e841619eaf26e340a3e707295a0abf59feb6a469 192.168.220.134:7004
       slots:[10923-16383] (5461 slots) master
    S: fb9e3cc8e101e93da5d4ccea8153ebfbd6435085 192.168.220.134:7005
       replicates c30c612e164c9203f4a2efb1dc63c951572ad417
    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join
    .....
    >>> Performing Cluster Check (using node 192.168.220.132:7000)
    M: cb6d97578ad557a6ab5acfd5a49f8ee1cf10d53e 192.168.220.132:7000
       slots:[0-5460] (5461 slots) master
       1 additional replica(s)
    M: e841619eaf26e340a3e707295a0abf59feb6a469 192.168.220.134:7004
       slots:[10923-16383] (5461 slots) master
       1 additional replica(s)
    S: 944e29825311f57384e93dcedd153b5bbf0e9ddc 192.168.220.133:7003
       slots: (0 slots) slave
       replicates cb6d97578ad557a6ab5acfd5a49f8ee1cf10d53e
    M: c30c612e164c9203f4a2efb1dc63c951572ad417 192.168.220.133:7002
       slots:[5461-10922] (5462 slots) master
       1 additional replica(s)
    S: fb9e3cc8e101e93da5d4ccea8153ebfbd6435085 192.168.220.134:7005
       slots: (0 slots) slave
       replicates c30c612e164c9203f4a2efb1dc63c951572ad417
    S: ccc9f32340c96ef86e38728f2c5f1a690301273f 192.168.220.132:7001
       slots: (0 slots) slave
       replicates e841619eaf26e340a3e707295a0abf59feb6a469
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    

    数据验证

    [root@k8s-node1 ~]# redis-cli -c -h 192.168.220.132 -p 7000
    192.168.220.132:7000> keys *
    (empty array)
    192.168.220.132:7000> set name zhangsan
    -> Redirected to slot [5798] located at 192.168.220.133:7002
    OK
    192.168.220.133:7002> get name
    "zhangsan"
    [root@k8s-node2 ~]# redis-cli -c -h 192.168.220.134 -p 7004
    192.168.220.134:7004> 
    192.168.220.134:7004> get name
    -> Redirected to slot [5798] located at 192.168.220.133:7002
    "zhangsan"
    192.168.220.133:7002> keys *
    1) "name"
    192.168.220.133:7002> 
    

    在哪个服务器上写数据:CRC161

    redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

    Redis集群没有使用传统的一致性哈希来分被数据,而是采用另一种叫做哈希槽(hash slot)的方式来分配的。redis cluster默认分配了16384个slot,当我们set一个key时,会用CRC16算法来取模得到所属的slot,然后将这个key分到哈希槽区间的节点上,具体的算法上就是:CRC16(key) % 16384。所以我们在测试的时候看到set和get时,直接跳转到了7002端口的节点。

    Redis集群会把数据存在一个master节点,然后在这个master和其对应的slave之间进行数据同步。当读取数据时,也根据一致性哈希算发到对应的master节点获取数据。只有当一个master挂掉之后,才会启动一个对应的slave节点,充当master

    需要注意:必须使用3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总结点数的一半时,整个集群就无法提供服务了。

    与Python交互

    安装包如下:pip install redis-py-cluster

    redis-py-cluster源码地址( http://github.com/Grokzen/redis-py-cluster)

    创建文件redis_cluster.py,示例代码如下

    from rediscluster import *
    
    if __name__ == '__main__':
        try:
    
            # 构建所有的节点,Redis会使用CRC16算法,将键和值写到某个节点上
            startup_nodes = {
                {'host': '192.168.220.132','port':'7000'},
                {'host': '192.168.220.133','port':'7002'},
                {'host': '192.168.220.134','port':'7004'},
            }
            # 构建StrictRedisCluster对象
            src = StrictRedisCluster(startup_nodes=startup_nodes, decode_response=True)
            # 设置键为name,值为zhangsan的数据
            result = src.set('name', 'zhangsan')
            print(result)
            # 获取键为name
            name = src.get('name')
            print(name)
        
        except Exception as e:
            print(e)
    

    相关文章

      网友评论

          本文标题:redis

          本文链接:https://www.haomeiwen.com/subject/slxkohtx.html