redis

2020-05-15  本文已影响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)
上一篇下一篇

猜你喜欢

热点阅读