百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

redis的简单与集群搭建(redis建立集群)

bigegpt 2025-06-08 19:28 1 浏览

Redis是什么?

是开源免费用c语言编写的单线程高性能的(key-value形式)内存数据库,基于内存运行并支持持久化的nosql数据库

作用

主要用来做缓存,单不仅仅是做缓存,比如:redis的计数器生成分布式的唯一主键,redis实现分布式锁、队列、会话缓存等等。

redis数据类型及api操作(http://redisdoc.com/)

key

keys * 查询所有的键

scan 0 match * count 1 查询所有键从下角标0开始,返回1个键数据的结果集

exists key 判断某个key是否存在

move key db 当前库就没有了,到指定的库中去了

expire key 为给定的key设置过期时间

ttl key 查看还有多少时间过期 -1表示永不过期 -2表示已过期

type key 查看key是什么类型

1.string

一般使用场景:单值缓存、对象缓存、分布式锁、计数器、websession共享、分布式全局序列号

string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。

string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。

string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M

set key value 设置key value

get key 查看当前key的值

del key 删除key

append key value 如果key存在,则在指定的key末尾添加,如果key存在则类似set

strlen key 返回此key的长度

以下几个命令只有在key值为数字的时候才能正常操作


incr key 为执定key的值加一

decr key 为指定key的值减一

incrby key 数值 为指定key的值增加数值

decrby key 数值 为指定key的值减数值


getrange key 0(开始位置) -1(结束位置) 获取指定区间范围内的值,类似between......and的关系 (0 -1)表示全部

setrange key 1(开始位置,从哪里开始设置) 具体值 设置(替换)指定区间范围内的值

setex 键 秒值 真实值 设置带过期时间的key,动态设置。

setnx key value 只有在 key 不存在时设置 key 的值。

mset key1 value key2 value 同时设置一个或多个 key-value 对。

mget key1 key 2 获取所有(一个或多个)给定 key 的值。

msetnx key1 value key2 value 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。

getset key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。

2.list

一般使用场景:公众号消息流、

它是一个字符串链表,left、right都可以插入添加;如果键不存在,创建新的链表;如果键已存在,新增内容;如果值全移除,对应的键也就消失了。链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了。

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。它的底层实际是个链表

lpush key value1 value2 将一个或多个值加入到列表头部

rpush key value1 value2 将一个或多个值加入到列表底部

lrange key start end 获取列表指定范围的元素 (0 -1)表示全部

lpop key 移出并获取列表第一个元素

rpop key 移出并获取列表最后一个元素

lindex key index 通过索引获取列表中的元素

llen 获取列表长度

lrem key 0(数量) 值,表示删除全部给定的值。零个就是全部值 从left往right删除指定数量个值等于指定值的元素,返回的值为实际删除的数量

ltrim key start(从哪里开始截) end(结束位置) 截取指定索引区间的元素,格式是ltrim list的key 起始索引 结束索引

3.set

一般使用场景:微信抽奖程序、微信点赞、收藏标签、关注模型

Redis的Set是string类型的无序,不能重复的集合。

sadd key value1 value 2 向集合中添加一个或多个成员

smembers key 返回集合中所有成员

sismembers key member 判断member元素是否是集合key的成员

scard key 获取集合里面的元素个数

srem key value 删除集合中指定元素

srandmember key 数值 从set集合里面随机取出指定数值个元素 如果超过最大数量就全部取出,

spop key 随机移出并返回集合中某个元素

smove key1 key2 value(key1中某个值) 作用是将key1中执定的值移除 加入到key2集合中

sdiff key1 key2 在第一个set里面而不在后面任何一个set里面的项(差集)

sinter key1 key2 在第一个set和第二个set中都有的 (交集)

sunion key1 key2 两个集合所有元素(并集)

4.hash

一般使用场景:对象缓存、电商购物车、

Redis hash 是一个键值对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

kv模式不变,但v是一个键值对

类似Java里面的Map

优点:同类数据归类整合存储,方便数据管理;相对于string消耗的内存与cpu更小;相比于string更省存储空间

缺点:过期功能不能用于field(里层)只能作用于key(外层)上;redis集群架构下不适合大规模使用

hset key (key value) 向hash表中添加一个元素

hget key key 向hash表中获取一个元素

hmset key key1 value1 key2 value2 key3 value3 向集合中添加一个或多个元素

hmget key key1 key2 key3 向集合中获取一个或多个元素

hgetall key 获取在hash列表中指定key的所有字段和值

hdel key key1 key2 删除一个或多个hash字段

hlen key 获取hash表中字段数量

hexits key key 查看hash表中,指定key(字段)是否存在

hkeys key 获取指定hash表中所有key(字段)

hvals key 获取指定hash表中所有value(值)

hincrdy key key1 数量(整数) 执定hash表中某个字段加 数量 ,和incr一个意思

hincrdyfloat key key1 数量(浮点数,小数) 执定hash表中某个字段加 数量 ,和incr一个意思

hsetnx key key1 value1 与hset作用一样,区别是不存在赋值,存在了无效。

5.zset

一般使用场景:排行榜

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

zadd key score 值 score 值 向集合中添加一个或多个成员

zrange key 0 -1 表示所有 返回指定集合中所有value

zrange key 0 -1 withscores 返回指定集合中所有value和score

zrangebyscore key 开始score 结束score 返回指定score间的值

zrem key score某个对应值(value),可以是多个值 删除元素

zcard key 获取集合中元素个数

zcount key 开始score 结束score 获取分数区间内元素个数

zrank key vlaue 获取value在zset中的下标位置(根据score排序)

zscore key value 按照值获得对应的分数

conf文件的注意点

1.bind可以使用0.0.0.0或者机器的IP地址

2.protected-mode在使用bind或者设置了密码时是无效的

3.protected-mode默认是开启的,不能被外网访问的

4.当redis以守护进程方式运行时,redis默认会把pid写入redis.pid文件,可以使用pidfile指定(只适用于linux版本,window不适用)

5.logfile指定日志文件的位置

6.databases是数据库的数目,默认是16

redis的单线程和多性能

redis是单线程吗:redis的单线程只要是指redis的网络io和键值对读写是由一个线程来完成的,这也是redis对外提供键值存储服务的主要流程。但是redis的其他功能,如持久化、异步删除、数据同步等都是由额外的线程执行的。

redis单线程为什么还能这么快:因为它所有的数据都在内存中,所有的运算都是内存级别的运算,并且单线程避免了线程切换的损耗问题。正是由于redis是单线程所以要小心使用redis指令,对于那些耗时的指令(如keys),需要谨慎使用,不小心会导致redis卡顿

redis单线程如何处理多个并发客户端的连接:redis的io多路复用,redis利用epoll来实现io多路复用,将连接信息和事件放到队列总,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。

持久化RDB(丢失数据较多)

  • 原理:redis会单独创建(fork)一个与当前线程一样的子线程来进行持久化,这子线程的所有数据都和原线程一模一样,会先将数据希尔到一个临时的文件中,等到持久化结束了再用这个临时文件替换上次持久化好的文件,整个过程中,主线程不进行任何的io操作,这就确保了极高的性能。
  • 持久化文件存放的位置:由dbfilename指定
  • 什么时候fork子进程,或者什么时候触发rdb持久化机制:

shutdow时,没有开启aof会触发

配置文件中默认的快照配置

执行命令save或者bgsave,save是主线程操作会阻塞,save只管保存,其余不管,bgsave是新fork线程后台操作

执行flushall命令(清空所有数据),无意义

  • 怎么开启rdb持久化

配置文件中配置save命令:save 900 1;表示900秒由一条数据更新会触发rdb的持久化机制

可以写多个save条件

当配置主从复制集群时,是关闭不了rdb的

持久化aof(丢失数据较少)

  • 原理:将redis的操作日志以追加的方式写入文件,读操作是不记录的
  • 怎么开启aof:配置文件中appendonly 设置为yes;命令行:config set appendonly yes,然后还是需要修改配置文件
  • 持久化文件在哪里:配置文件中 appendfilename指定
  • 触发机制(配置文件中appendfsync指定):no表示等操作系统进行数据缓存同步到磁盘(快,没保障);always同步持久化,每次发送数据变更时,立即记录到磁盘(慢,安全);everysec表示美妙同步一次(默认值,快,可能会丢失一秒以内的数据)
  • aof文件中日志解析:*2代表是2组命令;$6,$3代表是这个命令有6个,3个字符组成(命令长度);
  • aof的重写机制:当aof增长到一定大小时候redis可以调用bgreweiteaof命令对日志文件进行重写;当文件大小的增长率大于配置项时自动开启重写,是配置文件中auto-aof-rewrite-percentage指定表示超过源文件大小的百分之多少,案例:50;当文件大小大于配置项的大小时自动开启重写,是配置文件中的auto-aof-rewrite-min-size指定,案例:64mb

rdb与aof是可以同时开启时,默认使用aof持久化,所以切换rdb与aof时,最好通过命令行的方式启动aof,这样不会有数据丢失

混合持久化

  • 4.0版本的混合持久化是默认关闭的,可以通过配置文件中的aof-use-rdb-preamble来控制,yes代表开启,no表示禁用,5.0之后默认开启
  • 混合持久化是通过bgrewriteaof完成的,当开启混合持久化时,fork的子线程先将共享的内存副本全量的以rdb的方式写入aof文件,然后再将重写缓存区的增量命令以aof 的方式写入文件,完成后通知主线程更新统计信息,将新的aof文件替换旧的aof文件
  • 优点:加载速度快,同时结合aof 的方式保存,数据丢失少
  • 缺点:兼容性差,一旦开启混合持久化,在4.0版本之前都不识别该aof文件,阅读性差。

缓存穿透问题

缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,并且出于容错考虑, 如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

可能造成原因:

1.业务代码自身问题2.恶意攻击。爬虫等等

危害

对底层数据源压力过大,有些底层数据源不具备高并发性。 例如mysql一般来说单台能够扛1000-QPS就已经很不错了

解决方案

1.缓存空对象

缺点:可能会缓存大量空对象,当缓存过期时仍然会有缓存穿透的问题

public class NullValueResultDO implements Serializable{
     private static final long serialVersionUID = -6550539547145486005L;
}
 
public class UserManager {
     UserDAO userDAO;
     LocalCache localCache;
 
     public UserDO getUser(String userNick) {
          Object object = localCache.get(userNick);
          if(object != null) {
               if(object instanceof NullValueResultDO) {
                    return null;
               }
               return (UserDO)object;
          } else {
               User user = userDAO.getUser(userNick);
               if(user != null) {
                    localCache.put(userNick,user);
               } else {
                    localCache.put(userNick, new NullValueResultDO());
               }
               return user;
          }
     }          
}

2.布隆过滤器

缺点:添加数据时,布隆过滤器也需要添加数据,但是不能删除数据,所以要定时维护更新布隆过滤里面的数据

1)、Google布隆过滤器的缺点

基于JVM内存的一种布隆过滤器重启即失效本地内存无法用在分布式场景不支持大数据量存储

2)、Redis布隆过滤器

可扩展性Bloom过滤器:一旦Bloom过滤器达到容量,就会在其上创建一个新的过滤器不存在重启即失效或者定时任务维护的成本:基于Google实现的布隆过滤器需要启动之后初始化布隆过滤器缺点:需要网络IO,性能比Google布隆过滤器低

缓存击穿.热点key重建缓存问题

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

我们知道,使用缓存,如果获取不到,才会去数据库里获取。但是如果是热点 key,访问量非常的大,数据库在重建缓存的时候,会出现很多线程同时重建的情况。因为高并发导致的大量热点的 key 在重建还没完成的时候,不断被重建缓存的过程,由于大量线程都去做重建缓存工作,导致服务器拖慢的情况。

解决方案

1.互斥锁

第一次获取缓存的时候,加一个锁,然后查询数据库,接着是重建缓存。这个时候,另外一个请求又过来获取缓存,发现有个锁,这个时候就去等待,之后都是一次等待的过程,直到重建完成以后,锁解除后再次获取缓存命中。

 
public String getKey(String key){
    String value = redis.get(key);
    if(value == null){
        String mutexKey = "mutex:key:"+key; //设置互斥锁的key
        if(redis.set(mutexKey,"1","ex 180","nx")){ //给这个key上一把锁,ex表示只有一个线程能执行,过期时间为180秒
          value = db.get(key);
          redis.set(key,value);
          redis.delete(mutexKety);
  }else{
        // 其他的线程休息100毫秒后重试
        Thread.sleep(100);
        getKey(key);
  }
 }
 return value;
}

互斥锁的优点是思路非常简单,具有一致性,但是互斥锁也有一定的问题,就是大量线程在等待的问题。存在死锁的可能性。

缓存雪崩问题

缓存雪崩是指机器宕机或在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。

1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

4:如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。

redis的集群

  • 主从架构

原理:若为master配置了一个slave,不管这个slave是否是第一次连接上master,它都会发送psync命令给master请求复制数据。master收到命令后,会在后台进行数据持久化通过bgsave上次最新的rdb快照文件,持久化时,master会继续接受客户端请求,他会把可能修改的数据及的请求缓存在内存中。当持久化进行完毕之后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后在加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。

当master与slave之间的连接由于某些原因断开时,slave能过自动连接master,如果master收到了多个salve并发连接请求,他只会进行一次持久化,而不是一个连接一次,然后再问吧这份持久化数据发送给多个并发连接的slave。

解决主从风暴的问题方法:配置阶梯式主从架构

配置从节点实例,复制conf文件:

port 6389
pidfile /var/run/redis_6380.pid #把pid进程号写入pidfile配置文件
logfile "6380.log"
dir /usr/local/redis-5.0.3/data/6389 #指定数据存放目录


#配置主从复制
replicaof 127.0.0.1:6379 #从本机的6379redis实例复制数据,redis5.0之前用slaveof
replica-read-only yes #配置从节点只读


#启动从节点
redis-server redis.conf

#连接从节点
redis-cli -p 6380

#测试在6379实例上写数据,6380实例是否能及时同步数据

同步骤配置下一个从节点
  • 哨兵模式的主从架构

原理:哨兵是特殊的redis服务,不提供读写服务,主要来健康redis实例的节点,哨兵架构下的client端第一次从哨兵中找出redis的主节点,后续就直接访问redis的主节点,不是每次都通过哨兵进行代理访问redis的主节点,当redis的主节点变化时,哨兵会第一时间感知到,并且将新的redis节点通知给client端(这里的redis的client端一般都实现了订阅功能,订阅哨兵发布的节点变动消息)

配置搭建:

复制一份sentinel.conf文件

修改相关配置:
port  26379
daemonize yes
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.3/data"

#sentinel monitor <master-name> <ip> <redis-port> <quorum>
#quorum是数字,指明当前有多少sentinel认为master失效时(一般是 总数/2+1),master才算真正失效
sentinel monitor mymaster 192.168.0.60:6379 2

注释掉bind IP那行代码

protected-mode no 关闭自我保护模式,开启只有本机可以访问

启动哨兵实例
redis-sentinel redis-sentinel-26379.conf

查看sentinel的info信息
redis-cli -p 26379
info
可以看到sentinel的info里已经识别出redis的主从

同步骤可以配置其余的哨兵
  • redis高可用集群cluster(最少需要三个主节点)

原理:redis cluster将所有数据划分为16384个槽位,每个节点负责其中一部分槽位,槽位的信息存储在每个节点中。

当集群的客户端连接集群时,他会得到一份集群的槽位配置信息并将其缓存在客户端本地,这样当客户端要查找某个key时,可以直接定位目标节点,同时因为信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。

跳转重定向:当客户端向一个错误的节点发出指令,该节点会发现指令大key所在的槽位并不归自己管理,这时她会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连接这个节点获取数据,客户端收到指令后处理跳转到正确的节点上操作,还会同步更新纠正本地的槽位映射表缓存,后续所有可以将使用新的槽位表映射表。

配置:

daemonize yes 后台启动
protect-mode no 关闭保护模式,开启的话本机才可以访问redis

注释掉bind


redis集群至少需要三个master节点,我们搭建三个master并且给每个master搭建一个slave节点

在第一台机器的/usr/local下创建文件夹redis-cluster,然后在其下面分别创建2个文件夹
mkdir -p /usr/local/redis-cluster
mkdir 8001 8004

把之前的redis.conf配置文件copy到8001下,修改内容:
daemonize yes
port 8001
dir /usr/local/redis-cluster/8001/ (指定数据文件位置,必须要指定不同的目录位置,不然会丢失数据)
cluster-enabled yes  启动集群模式
cluster-config-file nodes-8001.conf集群节点信息文件
cluster-node-timeout 5000
protected-mode no
appendonly yes

如果要设置密码需要如下配置
requirepass mima  redis的访问密码
masterauth mima  集群的访问密码,与上面一致


上述步骤配置其他节点,端口号不同


#启动从节点
redis-server redis.conf

构建集群命令(最后的数字是一个主节点对应多少个从节点的意思),只需构建一次,服务器重启不需要重启构建
redis5.0使用/usr/local/bin/redis-cli --cluster create 192.168.0.104:7000 192.168.0.104:7001 192.168.0.104:7002 192.168.0.104:7003 192.168.0.104:7004 192.168.0.104:7005 --cluster-replicas 1

相关推荐

10w qps缓存数据库——Redis(redis缓存调优)

一、Redis数据库介绍:Redis:非关系型缓存数据库nosql:非关系型数据库没有表,没有表与表之间的关系,更不存在外键存储数据的形式为key:values的形式c语言写的服务(监听端口),用来存...

Redis系列专题4--Redis配置参数详解

本文基于windowsX64,3.2.100版本讲解,不同版本默认配置参数不同在Redis中,Redis的根目录中有一个配置文件(redis.conf,windows下为redis.windows....

开源一夏 | 23 张图,4500 字从入门到精通解释 Redis

redis是目前出场率最高的NoSQL数据库,同时也是一个开源的数据结构存储系统,在缓存、数据库、消息处理等场景使用的非常多,本文瑞哥就带着大家用一篇文章入门这个强大的开源数据库——Redis。...

redis的简单与集群搭建(redis建立集群)

Redis是什么?是开源免费用c语言编写的单线程高性能的(key-value形式)内存数据库,基于内存运行并支持持久化的nosql数据库作用主要用来做缓存,单不仅仅是做缓存,比如:redis的计数器生...

推荐几个好用Redis图形化客户端工具

RedisPlushttps://gitee.com/MaxBill/RedisPlusRedisPlus是为Redis可视化管理开发的一款开源免费的桌面客户端软件,支持Windows、Linux...

关于Redis在windows上运行及fork函数问题

Redis在将数据库进行持久化操作时,需要fork一个进程,但是windows并不支持fork,导致在持久化操作期间,Redis必须阻塞所有的客户端直至持久化操作完成。微软的一些工程师花费时间在解决在...

你必须懂的Redis十大应用场景(redis常见应用场景)

Redis作为一款高性能的键值存储数据库,在互联网业务中有着广泛的应用。今天,我们就来详细盘点一下Redis的十大常用业务场景,并附上Golang的示例代码和简图,帮助大家更好地理解和应用Redis。...

极简Redis配置(redis的配置)

一、概述Redis的配置文件位于Redis安装目录下,文件名为redis.conf(Windows名为redis.windows.conf,linux下的是redis.conf)你可以通过C...

什么是redis,怎么启动及如何压测

从今天起咱们一起来学习一下关于“redis监控与调优”的内容。一、Redis介绍Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。...

一款全新Redis UI可视化管理工具,支持WebUI和桌面——P3X Redis UI

介绍P3XRedisUI这是一个非常实用的RedisGUI,提供响应式WebUI访问或作为桌面应用程序使用,桌面端是跨平台的,而且完美支持中文界面。Githubhttps://github....

windows系统的服务器快速部署java项目环境地址

1、mysql:https://dev.mysql.com/downloads/mysql/(msi安装包)2、redis:https://github.com/tporadowski/redis/r...

window11 下 redis 下载与安装(windows安装redis客户端)

#热爱编程是一种怎样的体验#window11下redis下载与安装1)各个版本redis下载(windows)https://github.com/MicrosoftArchive/r...

一款轻量级的Redis客户端工具,贼好用!

使用命令行来操作Redis是一件非常麻烦的事情,我们一般会选用客户端工具来操作Redis。今天给大家分享一款好用的Redis客户端工具TinyRDM,它的界面清新又优雅,希望对大家有所帮助!简介Ti...

一个.NET开发且功能强大的Windows远程控制系统

我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!项目介绍SiMayRemoteMonitorOS是一个基于Windows的远程控制系统,完...

Redis客户端工具详解(4款主流工具)

大家好,我是mikechen。Redis是大型架构的基石,也是大厂最爱考察内容,今天就给大家重点详解4款Redis工具@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集...