redis

xiaoxiao2025-04-12  16

下载: wget http://download.redis.io/releases/redis-3.0.7.tar.gz tar -xzf redis-3.0.7.tar.gz ln -s redis-3.0.7 redis cd redis make make install

安装完之后 /usr/local/bin下多了几个以redis开头可执行文件, 这些文件可以启动和停止redis、可以检测和修复redis的持久化文件, 还可以检测redis的性能 redis-server 启动redis redis-cli redis命令行客户端 redis-benchmark redis基准测试工具 redis-check-aof redisAOF持久化文件检测和修复工具 redis-check-dump redisRDB持久化文件检测和修复工具 redis-sentinel 启动redis Sentinel

防火墙端口开放:  firewall-cmd --zone=public --add-port=3306/tcp --permanent 重启防火墙 firewall-cmd --reload

iptables -I INPUT -p tcp --dport 3306 -j ACCEPT

1,启动redis 有3种方法:默认配置、运行配置、配置文件启动 默认配置:redis-server 默认端口:6379

运行配置:redis-server --port 6380

运行配置文件启动:redis-server /opt/redis/redis.conf

2,redis命令行客户端 通过redis-cli连接redis、操作redis服务,

第一种是交互式方式: 通过redis-cli-h{host}-p{port}的方式,之后所有操作都是通过交互式的方式实现,不需要再执行redis-cli了 redis-cli -h 127.0.0.1 -p 6379

第二种命令方式:redis-cli-h{host} -p{port} {command} redis-cli -h 127.0.0.1 -p 6379 get hello

停止redis: redis-cli shutdown redis-cli shutdown nosave|save (注:是否持久化文件) 

redis基本使用: 1,查看所有键 keys *

2,键总数: dbsize

dbsize命令在计算键总数时不会遍历所有键,而是直接获取redis内置的键总数变量, 所以dbsize时间复杂度O(1); keys 会遍历所有键,时间复杂度O(n)

3检测键是否存在 exists key 如果存在返回1,不存在返回0;

4删除键: del key 返回结果为成功删除的键的个数,假设删除不存在的键就返回0; del key1 key2

5键过期: expire key seconds

6 ttl命令会返回键的剩余过期时间,它有3种返回值: 大于等于0的整数:键剩余的过期时间

-1键没设置过期时间 -2键不存在

7 键的数据类型,如果键不存在,返回none type key

string hase list set zset

redis 高性能的原因: 1,纯内存访问,内存访问长达100纳秒 2非阻塞IO,事件监听的模式 3,单线程避免了线程切换和竞争的消耗

设置值 set hello get hello 设置值并设置过期时间 setex hello 20 world

设置值时key不存在设置成功,已存在设置失败 setnx hello world 成功返回ok,失败返回0 分布式锁 setnx

2.2字符串 值最大512MB

批量设置值 mset key value [key value ..] mset a 1 b 2 c 3

批量获取值 mget a b c 键不存在,返回nil,按键的顺序返回

计数器 incr  对值做自增操作 值不是整数,返回错误 值是整数,返回自增后的结果 键不存在,按照值为0自增

incrby 自增指定数字

decr自减 decrby 自减指定数字

append 字符串后尾追加值 append key value

strlen 字符串字节长度 中文占3个字节

redis使用场景: 1,作为mysql的缓存 2,计数器,播放次数 3,共享session, 4,限速,例如短息验证码一段时间内不能发送多少次

哈希 key field value

hset key field value hget key field hdel key field [field...] hlen key 计算field的个数 或hset key field value1 value2...

批量设置和获取field-value hmget key field [field ..] hmset key field value [field value ..]

hexists key field 存在1,不存在0

获取所有field: hkeys 命令应该叫hfields更为恰当,它返回指定哈希键所有的field hkeys key

获取所有value hvals key

自增作用域field hincrby key field hincrbyfloat key field 

list:

从右添加 rpush key value 从左添加 lpush key value

查找 lrange key startIndex endIndex lrange key 0 -1

获取指定角标 lindex key index

列表长度 llen key

删除 从左弹出元素 lpop key 从右弹出元素 rpop key

删除指定元素 lrem key count value count >0 从左到右删除最多count个元素 count <0 从右到左删除count绝对值个元素 count =0 删除所有

修改指定索引元素 lset key index newValue

阻塞的pop:

blpop key timeout brpop key timeout 不为空会立刻返回

场景: 1,消息队列 redis的lpush+brpop命令组合即可实现阻塞队列, 生产者客户端使用lrpush从队列左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素, 多个客户端保证了消费的负载均衡和高可用

集合set:不允许重复 添加元素 sadd key element....

删除元素 srem key element ...

统计元素个数 scard key (注:直接用redis内部变量)

判断元素是否在集合中 sismember key element

随机返回指定个数元素, 不删除 srandmember key [count]

从集合随机弹出元素,会删除 spop key 

获取所有元素 smembers key

有序集合 zadd key score member

=======

bitMap

通过bit位来表示key的值或状态,Redis 从 2.2 版本之后新增了setbit, getbit, bitcount 等几个 bitmap 相关命令。

语法:SETBIT key offset value

 bit 的默认值是 0,那么 BitMap 在实际开发的运用呢?这里举一个例子:储存用户在线状态。这里只需要一个 key,然后把用户 ID 作为 offset,如果在线就设置为 1,不在线就设置为 0。实例代码:

//设置在线状态

setBit('online', userId, 1);

//设置离线状态

setBit('online', userId, 0);

//获取状态

getBit('online', userId);

//获取在线人数

bitCount('online');

======

Geo

1,geoadd:将给定的空间元素(纬度,经度,名字)添加到指定的键里面,这些数据会以有序集合的形式被存储在键里面。

geoadd online 13.32 38.26  driverId

2,geopos: 从键里面返回给定位置元素的位置(经度和纬度)

geopos online driverId

3,geodist: 返回给定位置之间的距离,默认单位:m

geodist online driverId1 driverId2

4,georadius

georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]

以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。距离单位和上面的一致,其中后面的选项:

WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。距离的单位和用户给定的范围单位保持一致。 WITHCOORD: 将位置元素的经度和维度也一并返回。 WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。这个选项主要用于底层应用或者调试, 实际中的作用并不大。

redis> GEORADIUS online15 37 200 km WITHDIST 1) 1) "Palermo"  2) "190.4424" 2) 1) "Catania"  2) "56.4413"

4删除地理位置:

jedisCluster.zrem(key, member)

 

 

 

 

 

 

 

 

 

 

 

复制配置有3种方式: 1,在配置文件中加入slaveof {masterHost} {masterPort} redis启动生效 2,redis—server启动命令后加入--slaveof {masterHost} {masterPort} 3,redis在运行中,slaveof {masterHost} {masterPort}动态配置

slaveof本身是异步的 复制搭建成功后,可以使用info replication 查看复制相关状态

在从节点执行slaveof no one 来断开和主节点的复制关系。注:不会删除从节点上的所有数据

切换主节点: slaveof {newMasterHost} {newMasterPort} 注:会删除从节点上的所有数据

对于数据比较重要,主节点会通过设置requrepass参数进行密码验证,这时所有的的客户端访问必须使用auth命令 实行校验。配置从节点masterauth与主节点密码保持一致。

只读: 默认情况下,从节点使用slave-read-only=yes配置为只读模式。由于复制是从主节点到从节点,对于从节点的任何修改,主节点不会感知;

传输延迟: 主从节点一般部署在不同机器上,复制时的网络延迟就成为需要考虑的问题,redis为我们 了repl-disable-tcp-nodelay参数用于控制TCP-NODELAY,默认关闭,说明如下:     当关闭时,主节点产生的命令数据无论大小都会及时地发送从节点,这样主从之间延迟 会变小,但增加了网络带宽的消耗。使用于主从之间网络环境良好的场景,如同机房;          当开启时,主节点会合并较小的tcp数据包从而节省带宽。默认发送时间间隔取决于linux内核,一般认为40毫秒。 这种配置节省了带宽但增大主从节点的延迟。使用于主从网络环境复杂或带宽紧张的场景,如跨机房部署;

部署主从节点时需要考虑网络延迟、带宽使用率、防灾级别等因素,如要求低延迟时建议同机架或同机房部署并关闭repl-disable-tcp-nodelay; 如考虑高容灾性,可以同城跨机房部署并开启repl-disable-tcp-nodelay.

 

=========== redis 持久化: RDB持久化时把当前进程数据生成快照保存到硬盘的过程。触发RDB持久化过程分为手动触发和自动触发。 1,触发机制 手动触发分别对应save和bgsave命令: save命令:阻塞当前redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。运行save命令对应的日志如下:     * DB saved on disk  bgsave命令:redis 进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。运行bgsave命令 对应的redis 日志如下: *Background saving started by pid 3151 *DB save on disk  *RDB:0 MB of memory userd by copy-on-write *Background saving terminated with success

显然bgsave命令是针对save阻塞问题做的优化。因此redis 内部所有的的涉及RDB的操作都采用bgsave 的方式,而save 命令已经废弃。 redis 内部自动触发: 1,从节点执行全量复制,主节点会自动触发bgsave生成的rdb文件并发送给从节点。 2,默认情况下执行shutdown 时,如果没有开启aof持久化功能则自动执行bgsave.

RDB流程: 1执行bgsave命令,redis 父进程判断档期是否存在正在执行的子进程,如果存在直接返回; 2父进程执行fork操作创建子进程,fork操作会阻塞父进程,通过info stats命令查看

指定持久化文件启动redis redis-server --port 6080 --dir /soft

集群 yum -y install gcc gcc-c++ && yum -y install cmake && yum -y install ncurses-devel && yum -y install autoconf && yum -y install perl perl-devel

mkdir soft &&cd soft wget http://download.redis.io/releases/redis-3.0.7.tar.gz tar -xzf redis-3.0.7.tar.gz ln -s redis-3.0.7 redis cd redis make make install

创建3个目录 conf 配置 data 数据 log 日志

mkdir /usr/local/bin/conf && mkdir /usr/local/bin/data && mkdir /usr/local/bin/log

cp redis.conf /usr/local/bin/conf/redis-6381.conf cp redis.conf /usr/local/bin/conf/redis-6382.conf cp redis.conf /usr/local/bin/conf/redis-6383.conf cp redis.conf /usr/local/bin/conf/redis-6384.conf cp redis.conf /usr/local/bin/conf/redis-6385.conf cp redis.conf /usr/local/bin/conf/redis-6386.conf 改端口 redis-6381.conf 每个节点配置如下: port 6381 #配置redis作为守护进程运行 daemonize yes #开启集群模式 cluster-enabled yes #节点超时 ,毫秒 cluster-node-timeout 15000 #集群内部配置文件 cluster-config-file "nodes-6381.conf" #日志文件: logfile "./log/redis-6381.log"

appendonly yes

启动各节点 cd /usr/local/bin redis-server ./conf/redis-6381.conf redis-server ./conf/redis-6382.conf redis-server ./conf/redis-6383.conf redis-server ./conf/redis-6384.conf redis-server ./conf/redis-6385.conf redis-server ./conf/redis-6386.conf

开放各自端口 firewall-cmd --zone=public --add-port=6381/tcp --permanent

firewall-cmd --zone=public --add-port=6382/tcp --permanent firewall-cmd --zone=public --add-port=6383/tcp --permanent firewall-cmd --zone=public --add-port=6384/tcp --permanent firewall-cmd --zone=public --add-port=6385/tcp --permanent firewall-cmd --zone=public --add-port=6386/tcp --permanent

firewall-cmd --zone=public --add-port=16381/tcp --permanent firewall-cmd --reload

iptables -I INPUT -p tcp --dport 16381 -j ACCEPT

节点加入集群(节点握手) 在节点6381: redis-cli -h 127.0.0.1 -p 6381

查看节点信息 cluster nodes

cluster info

ruby 环境 wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz tar xvf ruby-2.3.1.tar.gz cd ruby-2.3.1 ./configure -prefix=/usr/local/ruby make make install cd /usr/local/ruby sudo cp bin/ruby /usr/local/bin sudo cp bin/gem /usr/local/bin

安装rubygem redis依赖 wget http://rubygems.org/downloads/redis-3.3.0.gem

gem install -l redis-3.0.7.gem gem list --check redis gem

如果报错缺少: cannot load such file -- zlib yum -y install zlib-devel cd ruby-2.3.1/ext/zlib ruby ./extconf.rb make make install

安装redis-trib.rb

cp /soft/redis-3.0.7/src/redis-trib.rb /usr/local/bin

cd /usr/local/bin ./redis-trib.rb 执行redis-trib.rb 命令确认环境是否正确

创建集群 ./redis-trib.rb create --replicas 1 192.168.211.132:6384 192.168.211.133:6385 192.168.211.134:6386 192.168.211.128:6381 192.168.211.130:6382 192.168.211.131:6383

replicas 1 指每个主节点配置多少个从节点,这里1代表每个主节点配置一个从节点 先主后从

报错:槽被占用  ERR Slot 0 is already busy (Redis::CommandError)  登录每个节点: 清除:flushall 和cluster reset 或者删除节点配置文件,重启

手工集群命令 加入集群: cluster meet otherIP other port cluster meet 192.168.211.130 6382 分配槽命令: redis-cli -h 127.0.0.1 -p 6380 cluster addslots {0...5461} 让节点成为从节点: 在节点执行cluster replicate {nodeId} nodeId:为主节点节点id

集群完整性检查: redis-trib.rb check 127.0.0.16381

集群扩容: 1,准备节点(和之前一样) 2,加入集群

(     不借助第三方工具:     在集群内,任意节点执行     cluster meet 新节点ip 新节点端口     在:192.168.211.128 6381     cluster meet 192.168.211.135 6387     cluster meet 192.168.211.136 6388 )

线上建议用redis-trib.rb add-node 新节点ip:port 集群任意ip:port redist-trib.rb add-node 192.168.137:6387 192.168.136:6386

3,迁移槽和数据

流程:1目标节点准备导入槽  ,2源节点准备导出槽  , 3批量获取源节点槽对应的键 , 4导入给目标节点,5通知所有主节点,该槽已指派给了目标节点

使用第三方: 1)redis-trib.rb reshard host:port --from <source-node-id> --to <target-node-id> --slots <totalCount> --yes --timeout <arg> --pipeline <arg>

参数说明: host:port 必传,集群内任意节点地址 --from :源节点id ,多个逗号隔开 --to:目标节点id,只有一个 --slots:需要迁移槽的总数量 --yes:是否需要输入yes确认后再执行 --timeout: 控制每次迁移操作的超时时间,默认60 000毫秒 --pipeline:控制每次批量迁移键的数量,默认 10

redis-trib.rb reshard 192.168.211.130:6382  //输入迁移槽数量 how many slots do you want to move (from 1 to 16384)?1460 //输入目标节点id what is the receiving node ID? afab09215f07d426d754c930281d49b313875576 //输入源节点  done 结束 Source node #:7870e122c4f6b9cd9af8542fe665310b8c5ee3ce Source node #:e5c077acbfd838c443810808501ee38e71c38639 Source node #:e4acefc31e4c83d71fe53e5bccbdaac8452ed21c Source node #:done

确认无误后输入yes

注:由于槽用于hash运算本身顺序没有意义,因此无须强制要求节点负责槽的顺序

迁移之后使用redis-trib.rb rebalance 命令检查节点之间槽的均衡性,如果不均衡,会自动调节均衡 redis-trib.rb rebalance 192.168.211.128:6381

2)添加从节点 在还没有主节点的节点执行: cluster replicate 主节点id 在6388 节点: cluster replicate afab09215f07d426d754c930281d49b313875576

收缩集群: 流程: 下线节点 ,1节点持有槽 ,迁移槽到其他节点,通知其他节点忘记下线节点           2节点不持有槽 ,通知其他节点忘记下线节点

1,迁移槽和数据

把6383 和6386下线 6383是主节点,持有槽(12288-16383) 6386是从节点

把6383 节点均匀迁移槽到其他3个主节点,每个节点都迁移1365个槽

目标节点每次只能写一个,所以 redis-trib.rb reshard 要执行3次 redis-trib.rb reshard 192.168.211.128:6381 和扩容时一样道理

注:如果主节点不持有槽,从节点会自动指向其他主节点 建议迁移槽时,主节点剩余一个槽,把从节点下线之后再迁移主节点槽

2,让其他忘记节点 cluster forget {downNodeId} 线上不建议用这命令, 线上用redis-trib.rb del-node {host:port} {downNodeId}

redis-trib.rb del-node内部伪代码: 1,判断是否还持有槽,如果有,下线失败退出

2, 遍历所有节点:如果下线节点有从节点,则把从节点指向其他主节点         发送cluster forget 忘记节点命令      建议先下线从节点,防止不必要的全量复制

命令如下:

redis-trib.rb del-node 192.168.211.128:6381 从节点id redis-trib.rb del-node 192.168.211.128:6381 主节点id

redis-trib.rb del-node 192.168.211.128:6381 855907771dfcb29cc26a405ba2a59e9be8a375aa

redis-trib.rb del-node 192.168.211.128:6381 7870e122c4f6b9cd9af8542fe665310b8c5ee3ce

查看key所在的槽: cluster keyslot key

故障转移: 故障发现: 主观下线:某个节点认为另一个节点不可用,即下线状态,这个状态并不是最终的。 客观下线:集群内多个节点认为不可以用,真正下线,需要对该节点进行故障转移。

 

转载请注明原文地址: https://www.6miu.com/read-5028103.html

最新回复(0)