Redis入门学习

Redis 是一种开源(BSD 许可) 内存中数据结构存储,用作数据库、缓存和消息代理MQ。
Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制:

RDB:是Redis DataBase缩写快照
1、只有一个文件 dump.rdb,方便持久化。

2、容灾性好,一个文件可以保存到安全的磁盘。

3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能

4.相对于数据集大时,比 AOF 的启动效率更高。

AOF:持久化

AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。

当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。

1、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。

2、通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。

3、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))

缺点:

1、AOF 文件比 RDB 文件大,且恢复速度慢。

2、数据集大的时候,比 rdb 启动效率低。


redis 中的默认的过期策略是 volatile-lru 。
 maxmemory-policy volatile-lru

maxmemory-policy 六种方式:
#volatile-lru – >使用LRU算法删除使用过期集合的key
#allkeys-lru – >在主键空间中,优先移除最近未使用的key。
#volatile-random – >在设置了过期时间的键空间中,随机移除某个key。
#allkeys-random – >在主键空间中,随机移除某个key。
#volatile-ttl – >设置了过期时间的键空间中,具有更早过期时间的key优先移除。
#novaiction – >当内存使用达到阈值的时候,所有引起申请内存的命令会报错。


volatile为前缀的策略都是从已过期的数据集中进行淘汰。
allkeys为前缀的策略都是面向所有key进行淘汰。
LRU(least recently used)最近最少用到的。
LFU(Least Frequently Used)最不常用的。

每条数据都是 键值对
key 永远就是string 字符串 
value: string hash list set(无序集合)  zset(有序集合)

help lset(help命令+___ 帮助文档)

redis是内存数据库 如果没有持久化 那么数据断电及失效
save自动保存

jedis;采用直连  多线程操作 不安全的 避免的话需要 jedis pool 连接池 BIO
springboot lettuce  nettly

Redis 提供 strings、hashes、lists、set、(有序集合)sorted sets 

带范围查询的排序集合、位图(bitmaps)、超级日志(hyperloglogs)、地理空间(geospatial)索引和流等数据结构

Redis 内置复制(replication)、Lua 脚本(Lua scripting)、LRU 驱逐(LRU eviction)、事务(transactions)和不同级别的磁盘持久化(persistence)

通过 Redis Sentinel 哨兵 和 Redis Cluster 自动分区提供高可用性。

redis 端口号6379   redis是单线程的    基于内存操作  CPU不是redis性能瓶颈  是根据机器的内存和网络带宽 既然可以使用单线程来实现

多线程(cpu会上下文切换)   核心:redis是将所有的数据全部放在内存中,单线程操作效率就是最高的 多次读写就是一个cpu完成

切换数据库 select 1

dbsize查看大小

redis 默认有16个数据库 默认是第0个

清除当前数据库  flushdb

清除全部数据库  flushAll

-2代表无了

String字符串

exists ___ 判断健是否存在 
move __
expire__  设置过期时间

ttl __  查看键有效时间  返回大于0代表有效时间  返回-1 永久有效 -2键不存在 

type__   查看键对应值的类型
keys __键名
keys *  获取所有的值  
keys *_*
append 追加
strlen key1 长度

set key1 v1 设置值
get key1  获取值

set views 0
get views 
incr views    = ++
decr views    = --
incrby views 10 指定增10
decrby views 5  指定减5    
getrange key1 0 -1  

set key2
append key2 leon 追加值
get key2
setrange

setex(set with expire)设置过期时间
setnx(set if not exist) 不存在在设置 分布式锁
mset  k1 v1 k2 v2 k3 v3  同时设置多个键值对
mget k1 k2 k3

mset user:1:name zhangsan user:1:age 2
mget user:1:name user:1:age

getset db redis 如果不存在值 返回nil
get db
getset db mongodb 如果存在值 获取原来的值,并设置新的值
get db


list集合 (队列可以有重复值) 列表中每个值添加顺序排序
lpush list one  将一个或者多个值插入到列表头部

lrange list  0 -1 获取list中的值

lrange list  0 1  获取区间具体的值

rpush list right 将一个值或者多个值,插入到列表尾部

lpop list  左边移除第一个元素
rpop list  右边移除最后一个元素

lrem list 1 one 移除  (lrem键 count值 count=0删除指定的所有值)

lindex list (0,1,2)从左边开始获取   (-1,-2,-3,)从右边开始获取
llen list 返回列表的长度

ltrim list 1 2 截取指定的长度

rpoplpush 移除列表的最后一个元素 将元素移动到新的列表中

exists list

lset 将列表中指定下标的值替换为另一个值 更新操作

lset list index value(索引左边从0开始 右边从-1开始)

lset list 0 item 如果不存在列表我们更新报错
lset list 0 item 如果存在 更新当前下标的值

linsert  list  before "" ""  
linsert  list  after  "" ""  

Hash 集合 和string类型 没太大区别      key-value 用于变更的数据 user name age 用户信息之类的 经常变动的信息
hash中字段名(键)不可以重复
适用于对象的存储

hset myhash ___ 键 和 字段
hget myhash ___ 键 和 字段

hmset myhash field1 hello field2 world   设置多个
hmget myhash field1 field2   获取多个

hgetall myhash 获取全部的数据
hdel  myhash field1 删除hash指定key字段 对应value值也就消失了
hlen myhash
del 键
hexists myhash field1 判断hash中指定字段是否存在

hkeys myhash 获取所有的键
hvals myhash 获取所有的值

hset myhash field3 5 指定增量
hincrby myhash field3 1
hincrby myhash field3 -1

hsetnx myhash fild4 hello 如不存在可以设置

Set集合 (无序不能重复集合)  集合不允许重复的值  集合的值只能添加或删除 不能修改
sadd myset __
smembers myset 查看set
scard myset 获取里面元素个数的值
sismember myset ___ 判断某个值是不是在set集合中

srem myset hello  移除set集合中指定元素

srandmember myset 随机选出一个元素

spop myset  随机删除一些set集合中的元素

smove myset myset2 "" 两个键 之间的value移动

sdiff key1 key2  差集

sinter key1 key2 交集

sunion key1 key2 并集


ZSet(有序集合 有三个内容 键:索引(index) 分数(score) 值(value))  按照score从小到大排序 存储工资表排序   重要消息 带权重进行判断  排行榜应用实现
set的基础上 增加一个值 set k1 v1 zset k1 score 1 v1

zadd myset 1 one
zadd myset 2 two 3 three  添加多个值
zrange myset 0 -1
zrange myset 0 -1 withscores

zscore myset one 可以获取某个值的分数

zrangebyscore salary (-inf) (+inf)  最小值到最大值排序
zrevrange salary 0 -1 从大到小进行排序
zrangebyscore salary -inf +inf  withscores   显示全部用户附带成绩

zrangebyscore salary -inf  10000  withscores 显示工资小于10000的员工升序排序

zrem salary leon 移除有序集合中的指定元素

zremrangebyscore key min  max 指定范围的值

zcard salary 获取有序集合中个数

zcount myset 1 3 获取指定区间的成员数量

geospatial 地理位置
Redis Geo  推算出地理位置信息 两地之间的距离 范围内的人
geoadd
geoadd china:city 116.40 39.90 beijing

gendist china:city beijin shanghai    (可添加距离单位)
genhash
geopos china:city beijing chongqin  获取指定的经度和纬度
georadius  china:city 110 30 1000 km   这个经纬度为中心 寻找周围1000km内的城市

georadius  china:city 110 30 1000 km  withdist 显示到中间距离的位置

georadius  china:city 110 30 1000 km withcoor 显示他人的定位信息

georadiusbymember  地图的定位
 georadiusbymember china:city shanghai 400 km

Hyperloglog基数统计的算法 优点:占用内存是固定的
网页的UV  用户访问量 

pfadd mykey a b c d e f g h i j

pfcount mykey

pfmerge mykey3 mykey mykey2  合并成一个


 
Bitmaps: 位存储  统计用户信息  打卡   用户信息 活跃 不活跃 两个状态的 都可以使用Bitmaps
Bitmaps 位图 数据结构 都是操作二进制位进行记录的 

setbit sign 0 1
getbit sign 6

事务 redis单条命令保存原子性 但事务不保证原子性
redis事务没有隔离性 本质:一组命令的集合   一个事务的所有命令都是被序列化 按照顺序执行

一次性 顺序性 排他性

multi  开启事务 

set k1 k2
get k1 k2

exec   执行事务

multi  开启事务
set k1 k2
get k1 k2
discard 取消事务

悲观锁:
认为什么时候都会出问题 无论做什么都会加锁

乐观锁: 认为什么是都会不出问题,所有不会上锁
获取version

Redis测监视测试

set money 100
set out 0
watch money   监视money对象
multi  事务正常结束 

decrby money 20
incrby out 20
exec

unwatch  如发现事务执行失败 先解锁

watch money 获取最新的值 再次监视

jedis:  redis java连接开发工具   使用java操作Redis中间件 

redis持久化
RDB  redis  database
在指定的时间间隔将内存中的数据集快照写入磁盘  snapshot快照  将快照文件直接读到内存
rdb保存的文件是:  dump.rdb 都是在我们配置文件中快照进行配置的

rm -rf   删除当前目录下的所有文件

AOF   (append only file)
将我们所有命令记录下来(写的操作) history,恢复的时候把这个文件全部执行一遍

redis订阅发布

哨兵模式 监控后台主机是否有故障 自动从库转换为主库

redis缓存穿透和雪崩

缓存穿透:用户想要查询一个数据 发现redis内存数据库没有,向持久层数据库查询发现也没有 本次查询失败 当用户很多的时候,缓存都没有命中
都去持久层数据库 给持久层数据库造成很大的压力,这时候相当于 缓存穿透

布隆过滤器 数据结构  对所有可能查询的参数HASH形式存储 控制层进行校验 不符合丢弃 避免对底层存储系统的查询压力

缓存空对象  对返回的对象缓存起来, 同时设置一个过期时间, 之后再访问这个数据将从缓存中获取 保护后端数据源

缓存穿透  是查不到

缓存击穿 是查的量太大 缓存过期 把大量请求数据 同时访问持久化数据库 使得数据库瞬间压力过大

设置热点数据永不过期
加互斥锁
分布式锁:保证对于每个key同时只有一个线程去查询后端服务  其他线程没有获取分布式锁的权限 只需要等待 将高并发压力转移到了分布式锁
对分布式锁考验很大

缓存雪崩:指某个时间段 缓存集中过期失效 redis宕机

商品信息时间比较集中的放入缓存 设置缓存一个小时 过了之后 这批商品的缓存过期了 对这批商品查询的访问查询 都到了数据库上 对于数据库
产生周期性的压力波峰  所有请求达到存储层, 存储层调用量会暴增 造成存储层崩掉
 

redis高可用 多增几台redis
限流降级  通过加锁或者队列来控制读数据库写缓存的线程数量 对某个key只允许一个线程查询数据和写缓存 其他线程等待

数据预热
正式部署之前,把可能的数据先预先访问一遍,部分可能大量访问的数据就会预加载到缓存中, 将发送大量访问前手动触发加载缓存不同的key
设置不同的过期时间,让缓存失效的时间尽量均匀


Redis常用命令?

Keys pattern

*表示区配所有

以bit开头的

查看Exists  key是否存在

Set

设置 key 对应的值为 string 类型的 value。

setnx

设置 key 对应的值为 string 类型的 value。如果 key 已经存在,返回 0,nx 是 not exist 的意思。

删除某个key

第一次返回1 删除了 第二次返回0

Expire 设置过期时间(单位秒)

TTL查看剩下多少时间

返回负数则key失效,key不存在了

Setex

设置 key 对应的值为 string 类型的 value,并指定此键值对应的有效期。

Mset

一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置。

Getset

设置 key 的值,并返回 key 的旧值。

Mget

一次获取多个 key 的值,如果对应 key 不存在,则对应返回 nil。

incr

对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误,incr 一个不存在的 key,则设置 key 为 1

incrby

同 incr 类似,加指定值 ,key 不存在时候会设置 key,并认为原来的 value 是 0

Decr

对 key 的值做的是减减操作,decr 一个不存在 key,则设置 key 为-1

Decrby

同 decr,减指定值。

Append

给指定 key 的字符串值追加 value,返回新字符串值的长度。

Strlen

取指定 key 的 value 值的长度。

persist xxx(取消过期时间)

选择数据库(0-15库)

Select 0 //选择数据库

move age 1//把age 移动到1库

Randomkey随机返回一个key

Rename重命名

Type 返回数据类型

08

使用过Redis分布式锁么,它是怎么实现的?

先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。

如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?

set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!

09

使用过Redis做异步队列么,你是怎么用的?有什么缺点?

一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。

缺点:

在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。

能不能生产一次消费多次呢?

使用pub/sub主题订阅者模式,可以实现1:N的消息队列。

10

什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?

缓存穿透

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免?

1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免?

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

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

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

什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
Redis 提供了两种持久化方式:RDB(默认) 和AOF 
WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件
SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。


RESP 是redis客户端和服务端之前使用的一种通讯协议;
RESP 的特点:实现简单、快速解析、可读性好

1、aof文件比rdb更新频率高,优先使用aof还原数据。

2、aof比rdb更安全也更大

3、rdb性能比aof好

4、如果两个都配了优先加载AOF

Redis: 有哪些架构模式?讲讲各自的特点
单机版 1、内存容量有限 2、处理能力有限 3、无法高可用。

主从复制:  Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。
无法保证高可用
没有解决 master 写的压力

哨兵  Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性:

监控(Monitoring):    Sentinel  会不断地检查你的主服务器和从服务器是否运作正常。

提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作。

特点:

1、保证高可用

2、监控各个节点

3、自动故障迁移

缺点:主从模式,切换需要时间丢数据

没有解决 master 写的压力

集群(proxy 型):
特点:1、多种 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins 

2、支持失败节点自动删除

3、后端 Sharding 分片逻辑对业务透明,业务方的读写方式和操作单个 Redis 一致

缺点:增加了新的 proxy,需要维护其高可用。

集群(直连型):
特点:

1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。

2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。

3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本

5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。

缺点:

1、资源隔离性较差,容易出现相互影响的情况。

2、数据通过异步复制,不保证数据的强一致性


string
此类型和memcache相似,作为常规的key-value缓存应用。
例如微博数、粉丝数等
注:一个键最大能存储512MB
hash
redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象(应为对象可能会包含很多属性)
常用命令:hget hset hgetall
主要用来存储对象信息

list
list列表是简单的字符串列表,按照插入顺序排序(内部实现为LinkedList),可以选择将一个链表插入到头部或尾部
常用命令 :lpush(添加左边元素),rpush,lpop(移除左边第一个元素),rpop,lrange(获取列表片段,LRANGE key start stop)等。
应用场景:Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。
set
案例:在微博中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
zset
常用命令:zadd,zrange
实现方式:Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,跳跃表按score从小到大保存所有集合元素。使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。时间复杂度与红黑树相同,增加、删除的操作较为简单。
输入方式
应用场景:排行榜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hide17

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值