redis

Redis(Rometo Dictionary Server)

官网:https://redis.io
Rometo Dictionary Server翻译过来就是远程字典服务器。作为简单的一个理解:跨进程的hashMap。
他的优点很多:

  1. 高性能:写能够达到81000/S,读速能够达到110000次/秒
  2. 定时异步持久化(RDB[redis database]、AOF[append only file])
  3. 单key对应value可以达到1G
  4. 丰富的数据类型支持
  5. redis操作全部属于原子性

  6. 在这里插入图片描述

redis是什么

官网简介:

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

翻译过来就是:Redis是一个开源的(BSD许可),基于内存中的数据key-value结构存储,用作数据库,缓存和消息代理。它支持数据结构,如字符串、散列、列表、集合、使用范围查询的排序集合、位图、超loglog、使用半径查询的地理空间索引和流。Redis有内置的复制,Lua脚本,LRU驱逐,事务和不同级别的磁盘持久性,并提供高可用性通过Redis哨兵和自动分区与Redis集群。

用途:

因为数据库是查磁盘,而缓存是查内存,所以在性能上查缓存比数据库高了不是一星半点,用户在请求数据库的时候,如果查询到的结果不为空,则将该结果在返回的同时存入redis,如果以后有相同的请求(key一致),则直接请求缓存获取数据。极大的提升了应用程序和性能,减轻数据库压力,特别是数据查询方面。作为数据库的挡箭牌,副作用就是特别要求缓存数据与数据库数据的一致性问题,这个问题基本是无解的,如果对数据的一致性要求特别严格,例如订单、金额方面的数据。不建议使用redis。常用途径:token以及session共享、分布式锁、自增id、验证码等。

特性:

Redis支持数据的持久化,可以将内存中的数据保存进磁盘中,重启的时候可以再次加载进行使用。
Redis支持key-value类型的数据,同时还提供String字符串,list链表,set集合,zset有序集合,hash等数据结构的存储,这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
Redis支持数据的备份,即master-slave模式的数据备份。
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
丰富的特性 – Redis还支持 publish/subscribe, 通知, 设置key有效期等等特性。

相关名词解释:

缓存穿透:

  • 是指故意查询数据库中不存在的数据,缓存中自然没有,将并发的压力全部堆积到数据库中,严重甚至会引发数据库奔溃。

方案1:接口校验。在正常业务流程中可能会存在少量访问不存在 key 的情况,但是一般不会出现大量的情况,所以这种场景最大的可能性是遭受了非法攻击。可以在最外层先做一层校验,用户鉴权、数据合法性校验等,例如商品查询中,商品的ID是正整数,则可以直接对非正整数直接过滤等等。

方案2:缓存空值。当访问缓存和DB都没有查询到值时,可以将空值写进缓存,但是设置较短的过期时间,该时间需要根据产品业务特性来设置。

方案3:布隆过滤器。使用布隆过滤器存储所有可能访问的 key,不存在的 key 直接被过滤,存在的 key 则再进一步查询缓存和数据库。可把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

缓存雪崩:

  • 是指在某一个时间片刻,缓存过期集中失效。这种情况是由于在设置缓存过期时间集中一致导致,这并不是很致命的雪崩,比较致命的缓存雪崩,是缓存服务器某个节点宕机或断网。因为自然形成的缓存雪崩,一定是在某个时间段集中创建缓存,那么那个时候数据库能顶住压力,这个时候,数据库也是可以顶住压力的。无非就是对数据库产生周期性的压力而已。而缓存服务节点的宕机,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮。甚至引发数据库奔溃。

方案1:打散过期时间。不同的key,设置不同的过期时间(例如使用一个随机值)比较冷门的数据用随机值比较小的值,比较热门的数据过期时间延长,让缓存失效的时间点尽量均匀。

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

方案3:加互斥锁。缓存失效后,通过加锁或者队列来控制写缓存的线程数量。比如对某个key只允许一个线程操作缓存,其他线程等待。

方案4:热点数据不过期。该方式和缓存击穿一样,要着重考虑刷新的时间间隔和数据异常如何处理的情况。

方案5:对于宕机方面的雪崩,则要求用到redis集群的高可用性,尽量保证宕机有替用(主从+哨兵+redis集群),如果真的还是不幸全部宕机,则保证本地 ehcache 缓存 + hystrix 限流&降级(保证数据库能抗住的请求量外的请求进行降级,只要系统不死,用户刷新两次也能出来数据),避免 MySQL 被打死,并且做好redis的持久化,一旦重启,快速恢复数据

缓存击穿:

  • 是指一个数据(key)非常热门,经常被访问,一直扛压着高并发,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

方案1:热点数据不设置过期时间,后由定时任务去异步加载数据,更新缓存。这种方式适用于比较极端的场景,例如流量特别特别大的场景,使用时需要考虑业务能接受数据不一致的时间,还有就是异常情况的处理,不要到时候缓存刷新不上,一直是脏数据,那就凉了。

方案2:应用互斥锁。在并发的多个请求中,保证只有一个请求线程能拿到锁,并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。

关于互斥锁的选择,网上看到的大部分文章都是选择 Redis 分布式锁,因为这个可以保证只有一个请求会走到数据库,这是一种思路。但是其实仔细想想的话,这边其实没有必要保证只有一个请求走到数据库,只要保证走到数据库的请求能大大降低即可,所以还有另一个思路是 JVM 锁。JVM 锁保证了在单台服务器上只有一个请求走到数据库,通常来说已经足够保证数据库的压力大大降低,同时在性能上比分布式锁更好。需要注意的是,无论是使用“分布式锁”,还是“JVM 锁”,加锁时要按 key 维度去加锁。我看网上很多文章都是使用一个“固定的 key”加锁,这样会导致不同的 key 之间也会互相阻塞,造成性能严重损耗。(附上redis分布式锁的伪代码)

public Object loadData(String key) throws InterruptedException {
    Object value = redis.get(key);
    // 缓存值过期
    if (value == null) {
        // lockRedis:专门用于加锁的redis;
        // "empty":加锁的值随便设置都可以
        if (lockRedis.set(key, "empty", "PX", lockExpire, "NX")) {
            try {
                // 查询数据库,并写到缓存,让其他线程可以直接走缓存
                value = loadDataFromDb(key);
                redis.set(key, value, "PX", expire);
            } catch (Exception e) {
                // 异常处理
            } finally {
                // 释放锁
                lockRedis.delete(key);
            }
        } else {
            // sleep30ms后,进行重试
            Thread.sleep(30);
            return getData(key);
        }
    }
    return value;
}

缓存预热:

  • 是指对一些可预计比较常见的数据事先进行请求,以存入redis中。主要针对刚运行的服务器数据。

哈希槽:

  • 哈希槽是在redis cluster集群方案中采用的,redis cluster集群没有采用一致性哈希方案,而是采用数据分片中的哈希槽来进行数据存储与读取的。集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。(redis理论最大节点16383台)集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例,当超过一半的节点ping不通另一个节点,则认为该节点挂了。(redis集群至少需要3个节点,因为投票容错机制要求超过半数节点认为某个节点挂了该节点才是挂了,2个节点无法构成集群,节点数最好是奇数)

一致性哈希:

  • 一致性哈希用于解决分布式缓存系统中的数据选择节点存储问题和数据选择节点读取问题以及在增删节点后减少数据缓存的消失范畴,防止雪崩的发生。

RDB:

RDB方式是Redis数据库默认的持久化机制,是保证redis中数据可靠性的方式之一,这种方式可以按照一定的时间周期策略把内存中的数据以快照(二进制数据)的形式保存到磁盘文件中,即快照存储。对应产生的数据文件为dump.rdb。

                                     RDB配置参数介绍:
# 这里表示每隔60s,如果有超过1000个key发生了变更,就执行一次数据持久化。
# 这个操作也被称之为snapshotting(快照)。
save 60 1000
# 持久化 rdb文件遇到问题时,主进程是否接受写入,yes 表示停止写入,
# 如果是no 表示redis继续提供服务。
stop-writes-on-bgsave-error yes 
# 在进行快照镜像时,是否进行压缩。yes:压缩,
# 但是需要一些cpu的消耗。no:不压缩,需要更多的磁盘空间。
rdbcompression yes
# 一个CRC64的校验就被放在了文件末尾,当存储或者加载rbd文件的时候
# 会有一个10%左右的性能下降,为了达到性能的最大化,你可以关掉这个配置项。
rdbchecksum yes
# 快照的文件名
dbfilename dump.rdb
# 存放快照的目录
dir /var/lib/redis

- RDB持久化时机:

1、基于配置文件中的save规则周期性的执行持久化。

2、手动执行了shutdown操作会自动执行rdb方式的持久化。

3、手动调用了save或bgsave指令执行数据持久化。

4、主从复制(Master/Slave)架构下Slave连接到Master时,Master会对数据持久化,然后全量同步到Slave。

- RDB优点:

1、RDB 文件是经过压缩的二进制文件,占用空间很小,它保存了 Redis 某个时间点的数据集,很适合做备份。
2、RDB 非常适用于灾难恢复,它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心。
3、RDB 方式持久化性能较好,执行持久化时可以fork 一个子进程,由子进程处理保存工作,父进程无须执行任何磁盘 I/O 操作。

- RDB缺点:

1、RDB方式在服务器故障时容易造成数据的丢失。实际项目中,我们可通过配置来控制持久化的频率。但是, 如果频率太频繁,可能会对 Redis 性能产生影响。所以通常可能设置至少5分钟才保存一次快照,这时如果Redis 出现宕机等情况,则意味着最多可能丢失5分钟数据。

2、RDB 方式使用 fork 子进程进行数据的持久化,子进程的内存是在fork操作时父进程中数据快照的大小, 如果数据快照比较大的话,fork 时开辟内存会比较耗时,同时这个fork是同步操作,所以,这个过程会导致父进程无法对外提供服务。

3、RDB持久化过程中的fork操作,可能会导致内存占用加倍,Linux系统fork 子进程采用的是 copy-on-write的方式(写时复制,修改前先复制),在 Redis 执行 RDB 持久化期间,如果 client 写入数据很频繁,那么将增加 Redis 占用的内存,最坏情况下,内存的占用将达到原先的2倍。

AOF:

Redis中AOF方式的持久化是将Redis收到的每一个写命令都追加到磁盘文件的最后,类似于MySQL的binlog。当Redis重启时,会重新执行文件中保存的写命令,然后在内存中重建整个数据库的内容。

AOF 持久化默认是关闭的,可以通过配置appendonly yes 开启。当 AOF 持久化功能打开后,服务器在执行完一个写命令之后,会将被执行的写命令追加到服务器端 aof 缓冲区(aof_buf)的末尾,然后再将 aof_buf 中的内容写到磁盘。

Linux 操作系统中为了提升性能,使用了页缓存(page cache)。当我们将 aof_buf 的内容写到磁盘上时,此时数据并没有真正的落盘,而是存在在 page cache 中,为了将 page cache 中的数据真正落盘,需要执行 fsync / fdatasync 命令来强制刷盘。这边的文件同步做的就是刷盘操作,或者叫文件刷盘可能更容易理解一些。

                                        AOF持久化的优点

1、AOF 比 RDB更加可靠。你可以设置不同的 fsync 策略(no、everysec 和 always)。默认是everysec,在这种配置下,redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会
丢失一秒钟的数据。
2、AOF文件是一个基于纯追加模式的日志文件。即使日志因为某些原因而包含了未写入完整的命
令(比如写入时磁盘已满,写入中途停机等等), 我们也可以使用 redis-check-aof 工具也可以轻
易地修复这种问题。
3、当 AOF文件太大时,Redis 会自动在后台进行重写。重写后的新 AOF 文件包含了恢复当前数据
集所需的最小命令集合。整个重写是绝对安全,因为重写是在一个新的文件上进行,同时 Redis会继续
往旧的文件追加数据。当新文件重写完毕,Redis 会把新旧文件进行切换,然后开始把数据写到新文件上。
4、AOF 文件有序地保存了对数据库执行的所有写入操作,以 Redis 协议的格式保存, 因此 AOF 文件
的内容非常容易被人读懂, 对文件进行分析也很轻松。如果你不 小心执行了 FLUSHALL 命令把所有数
据刷掉了,但只要 AOF 文件没有被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis ,就可以将数据集恢复到 FLUSHALL 执行之前的状态。

                                         AOF持久化的缺点

对于相同的数据集,AOF 文件的大小一般会比 RDB 文件大。根据所使用的 fsync 策略,AOF 的速度可能会比 RDB 慢。通常 fsync 设置为每秒一次就能获得比较高的性能,而关闭 fsync 可以让 AOF 的速度和 RDB 一样快。AOF 可能会因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。虽然这种 bug 在 AOF 文件中并不常见, 但是相较而言, RDB 几乎是不可能出现这种 bug 的。

操作命令

1)连接操作命令
quit:关闭连接(connection)
auth:简单密码认证
help cmd: 查看cmd帮助,例如:help quit

2)持久化
save:将数据同步保存到磁盘
bgsave:将数据异步保存到磁盘
lastsave:返回上次成功将数据保存到磁盘的Unix时戳
shundown:将数据同步保存到磁盘,然后关闭服务

3)远程服务控制
info:提供服务器的信息和统计
monitor:实时转储收到的请求
slaveof:改变复制策略设置
config:在运行时配置Redis服务器

4)对value操作的命令
exists(key):确认一个key是否存在
del(key):删除一个key
type(key):返回值的类型
keys(pattern):返回满足给定pattern的所有key
randomkey:随机返回key空间的一个
keyrename(oldname, newname):重命名key
dbsize:返回当前数据库中key的数目
expire:设定一个key的活动时间(s)
ttl:获得一个key的活动时间
select(index):按索引查询
move(key, dbindex):移动当前数据库中的key到dbindex数据库
flushdb:删除当前选择数据库中的所有key
flushall:删除所有数据库中的所有key

5)  查看OR删除
keys *: 查看所有keys
keys prefix_*: 查看前缀为"prefix_"的所有keys
flushdb: 清除当前数据库的所有keys
flushall: 清除所有数据库的所有keys

数据类型以及对应场景

在这里插入图片描述

String(字符串):

可以为整形、浮点型和字符串最常用的数据类型,存储任何类型的字符串,包括二进制(图片、音频、视频)、JSON对象。在Redis中一个字符串最大的容量为512MB,redis的key限制也为512MB。

字符串类型也是其他 4 种数据库类型的基础,其它数据类型可以说是从字符串类型中进行组织的,如:列表类型是以列表的形式组织字符串,集合类型是以集合的形式组织字符串。
建议:“对象类型:对象ID:对象属性”命名一个键,如:“user:1:friends”存储 ID 为 1 的用户的的好友列表。对于多个单词则推荐使用 “.” 进行分隔。
在这里插入图片描述

set(key, value):给数据库中名称为key的string赋予值value
get(key):返回数据库中名称为key的string的value
getset(key, value):给名称为key的string赋予上一次的value
mget(key1, key2,…, key N):返回库中多个string的value
setnx(key, value):添加string,名称为key,值为value
setex(key, time, value):向库中添加string,设定过期时间time
mset(key N, value N):批量设置多个string的值
msetnx(key N, value N):如果所有名称为key i的string都不存在
incr(key):名称为key的string增1操作
incrby(key, integer):名称为key的string增加integer
decr(key):名称为key的string减1操作
decrby(key, integer):名称为key的string减少integer
append(key, value):名称为key的string的值附加value
substr(key, start, end):返回名称为key的string的value的子串

1)))数值类型常用于自增或者自减场合做统计。类似于点赞或者购物车商品数量加1之类统计。
在这里插入图片描述
2)))字符串常用于分布式锁实现以及对象json化存储。

// true:获取到锁    false:获取锁失败
private Boolean distributedLock(String lockStr,String expireSeconds){
    //NX和EX必须是一个原子操作,以免程序异常过期设置失败,用完需及时释放
	String result = jedisCluster.set(lockStr, "XXX", "NX", "EX", expireSeconds);
	return StringUtils.equals("ok",result)?true:false;
}

List(列表):实现队列,元素不唯一,先入先出原则

列表类型(list)可以存储一个有序的字符串列表,常用的操作是向两端添加元素。
列表类型内部是使用双向链表实现的,也就是说,获取越接近两端的元素速度越快,代价是通过索引访问元素比较慢。
在这里插入图片描述
在这里插入图片描述

rpush(key, value):在名称为key的list尾添加一个值为value的元素
lpush(key, value):在名称为key的list头添加一个值为value的 元素
llen(key):返回名称为key的list的长度
lrange(key, start, end):返回名称为key的list中start至end之间的元素
ltrim(key, start, end):截取名称为key的list
lindex(key, index):返回名称为key的list中index位置的元素
lset(key, index, value):给名称为key的list中index位置的元素赋值
lrem(key, count, value):删除count个key的list中值为value的元素
lpop(key):返回并删除名称为key的list中的首元素
rpop(key):返回并删除名称为key的list中的尾元素
blpop(key1, key2,… key N, timeout):lpop命令的block版本。
brpop(key1, key2,… key N, timeout):rpop的block版本。
rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

1)))list可以作为队列进行消费者生产者模型
在这里插入图片描述
2)))关于list队列下标图解(在获取元素的时候注意从左到右还是从右到左消费)
在这里插入图片描述

Hash(散列)

散列类型采用了字典结构(k-v)进行存储,适合存储对象。
散列类型建议命名方式:对象类别和 ID 构成键名,使用字段表示对象的属性,而字段值则存储属性值。
虽然String也可以保存一个对象,但是在直接操作缓存这块没有hash来得直接
在这里插入图片描述
常用命令:
在这里插入图片描述

hset(key, field, value):向名称为key的hash中添加元素field
hget(key, field):返回名称为key的hash中field对应的value
hmget(key, (fields)):返回名称为key的hash中field i对应的value
hmset(key, (fields)):向名称为key的hash中添加元素field 
hincrby(key, field, integer):将名称为key的hash中field的value增加integer
hexists(key, field):名称为key的hash中是否存在键为field的域
hdel(key, field):删除名称为key的hash中键为field的域
hlen(key):返回名称为key的hash中元素个数
hkeys(key):返回名称为key的hash中所有键
hvals(key):返回名称为key的hash中所有键对应的value
hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value

1)))hash适合存储一些复杂的对象,它操作的便捷性是String所不能比较的。例如:String更改对象属性还需要转换成对象,再进行属性更改,再转换成字符串存储。
在这里插入图片描述

Set(集合):key无序且不重复

在这里插入图片描述
通过set的无序且不重复,可以实现抽奖这种操作,十分符合场景。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

sadd(key, member):向名称为key的set中添加元素member
srem(key, member) :删除名称为key的set中的元素member
spop(key) :随机返回并删除名称为key的set中一个元素
smove(srckey, dstkey, member) :移到集合元素
scard(key) :返回名称为key的set的基数
sismember(key, member) :member是否是名称为key的set的元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, (keys)) :求交集并将交集保存到dstkey的集合
sunion(key1, (keys)) :求并集
sunionstore(dstkey, (keys)) :求并集并将并集保存到dstkey的集合
sdiff(key1, (keys)) :求差集
sdiffstore(dstkey, (keys)) :求差集并将差集保存到dstkey的集合
smembers(key) :返回名称为key的set的所有元素
srandmember(key) :随机返回名称为key的set的一个元素

1))):多个集合类型之间可以进行并集、交集和差集运算。
在这里插入图片描述
在这里插入图片描述
2)))通过交集、并集、合集等的计算可以实现以下场景:
在这里插入图片描述
在这里插入图片描述

Zset(有序集合):在集合类型的基础上添加了排序的功能。
在这里插入图片描述
在这里插入图片描述
1)))根据zset的特性也可以实现一些set不能办到的事情,因为set是无序的,而zset在统计那种顺序的场景,例如1号到30号,1月到12月,周榜,年榜,日榜之类的场景。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

bitmap:位图,其实也就是 byte 数组,用二进制表示,只有 0 和 1 两个数字。

type = string,BitMap 是 sting 类型,最大 512 MB

  • 优势

1.基于bit进行存储,大大节省了空间。
2.set时时间复杂度O(1)、get时时间复杂度O(n),操作快。
3.二进制方便计算机的运算
4.容易扩容

  • 限制

redis中bit映射被限制在512MB之内,所以最大是2^32位。建议每个key的位数都控制下,因为读取时候时间复杂度O(n),越大的串读的时间花销越多。bitmap空间、时间粗略计算方式
在一台2010MacBook Pro上,offset为232-1(分配512MB)需要~300ms,offset为230-1(分配128MB)需要~80ms,offset为228-1(分配32MB)需要~30ms,offset为226-1(分配8MB)需要8ms。<来自官方文档>

bitmap就是通过最小的单位bit来进行0或者1的设置,表示某个元素对应的值或者状态。
一个bit的值,或者是0,或者是1;也就是说一个bit能存储的最多信息是2。

getbit key offset	对key所存储的字符串值,获取指定偏移量上的位(bit)
setbit key offset value	对key所存储的字符串值,设置或清除指定偏移量上的位(bit)
7. 返回值为该位在setbit之前的值
8. value只能取0或1
9. offset从0开始,即使原位图只能10位,offset可以取1000
bitcount key [start end]	获取位图指定范围中位值为1的个数,如果不指定start与end,则取所有
bitop op destKey key1 [key2...]	做多个BitMap的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destKey中
bitpos key tartgetBit [start end]	计算位图指定范围第一个偏移量对应的的值等于targetBit的位置
10. 找不到返回-1
11. start与end没有设置,则取全部
12. targetBit只能取0或者1

hyperloglog:基于概率的数据结构。 # 2.8.9新增

Geo:地理位置信息储存起来, 并对这些信息进行操作 # 3.2新增

流(Stream)# 5.0新增

安装

  • redis是c语言开发的,需要c语言环境(yum会自动查找软件的相关依赖包,自动下载安装),by the way:
    yum是centos下更新、管理软件的命令;
    yum源是yum命令去哪里取安装包的地图;
    常见的yum源:网易、阿里云、epel等;
离线包安装:
yum -y install gcc    
yum -y install gcc-c++
redis源码上传到linux(可用连接工具WinSCP上传)
tar zxvf redis.tar.gz #包解压
cd redis  #进入redis目录
make install PREFIX=/xxx/xxx/redis  #后面是你安装的包路径
 
在线安装:
yum list | grep redis             # 检查yum是否有redis源
yum install epel-release          #没有下一个
yum install redis                 #好了,安装redis

命令:
service redis start/stop         #启动停止
service redis status             #查看redis运行状态
chkconfig redis on               #开机启动
systemctl start/stop redis       # centos7启动停止
systemctl status redis           # centos7查看redis运行状态
systemctl enable redis           # centos7开机启动
systemctl restart redis          # 重启redis

检查:
ps -ef | grep redis #可配合kill -9 强制杀掉redis进程

进入客户端(redis的bin目录下执行)
./redis-server
redis-cli
keys *                           #执行操作

停止两种方式
127.0.0.1:6379> shutdown
kill -9 (ps -ef | grep redis)  #这里是两行命令,这样是错的哈

在这里插入图片描述
启动成功后会出现这个玩意,按CTRL+C可以退出。

  • 修改配置
1) 打开配置文件:vi redis.conf  #需要从redis目录下复制到bin目录下才是依配置启动
2) 修改默认密码:查找 requirepass, 初使密码为 foobared
3) 找到 bind 127.0.0.1 将其注释,否则redis只允许本机连接
4) 找到 protected-mode yes 将其改为:protected-mode no 
5) port默认 6379,可改成你需要的
6) 重启Redis:systemctl restart redis  

redis-server /etc/redis.conf & #使用配置文件启动
redis-cli -h 127.0.0.1 -p 6379 #使用ip+端口登录
#如果添加密码之后,还需要 (auth xxx密码) 登录

连接

  • redis desktop manager远程连接redis
    下载它,好之后进行安装,新建一个连接,进入如下页面:
    在这里插入图片描述
    填写ip+端口即可进入。如果长时间连接不上,请检查redis-conf配置
[root@VMTest ~]# vi redis.conf
 
# 找到 bind 127.0.0.1 将其注释                      #只允许本地连接
# 找到 protected-mode yes 将其改为                  #开启保护模式
protected-mode no
  • java (jedis连接)
  1. maven依赖
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
  1. 配置文件(将jedis注入到spring容器)
package com.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashSet;
import java.util.Set;

@Configuration
//该注解表示只有JedisCluster.class实例存在时才会注入redisConifg配置
@ConditionalOnClass({JedisCluster.class})
public class RedisConfig {

    @Value("${spring.redis.cluster.nodes}")
    private String clusterNodes;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;
    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;
    @Value("${spring.redis.maxAttempts}")
    private int maxAttempts;

    @Bean
    public JedisCluster getJedisCluster() {
        Set<HostAndPort> nodes = new HashSet<>();
        // 分割出集群节点
        String[] cNodes = clusterNodes.split(",");
        for (String node : cNodes) {
            String[] hp = node.split(":");
            nodes.add(new HostAndPort(hp[0], Integer.parseInt(hp[1])));
        }
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 创建集群对象
        JedisCluster jedisCluster = new JedisCluster(nodes, timeout, maxAttempts, jedisPoolConfig);
        return jedisCluster;
    }
}
# 数据存储类
## MySql
### 基础囊括
### 命令
### 安装
# 负责均衡类
## Nginx
## Zookeeper
## SpringCloud
# 队列
## RabbitMQ
# 搜索引擎
## Lucene+Solr/ES
# 容器以及控制器
## Docker
## Kubernets
# Dubbo
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值