BAT面试必问之Redis数据类型底层原理

  • 时间:
  • 浏览:0
  • 来源:跟我学网络

为什么要学习使用Redis?

面试:

在面试,1-2道面试题。小公司偏向使用(1-3)。中大型公司偏重底层原理(3-5)

头条:头条, LIST底层实现原理

工作开发:

Redis一般开发分为单机版,集群版开发

php使用Redis 下载一下 Predis PHPredis

C/S

为什么使用Redis?

Redis非关系型数据库。存储模式key->value.. 数据存在内存

QPS>500 数据库搞不定

不单单做缓存: key->value string

数据类型:

基础:(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)

Bitmap geo(地图) storm()

中高级:Pub/Sub Hypreloglog

Redis的特点:

性能高(10w+qps)、原子性、丰富的数据类型、持久化的机制(RDB AOF)-->保存到磁盘、 3.0自带集群、高可用发、分布式

原子性:单线程

优点:

性能高:单线程 多路I/O复用(事件回调机制)。多线程有锁开销,单线程没有。进程之间通信消耗

缺点:

不能发挥多核的CPU的性能。 基于docker容器 部署多个Redis

性能瓶颈在网络I/O上(Redis6多线程,网络数据的读写和协议解析)、内存(扩容 、优化、)

Swoole 多进程模式

Redis应用场景:

1,缓存数据库:缓存。一般用于读多的场景下面,用于提升网站的访问速度。降低数据库的压力(缓存命令中率90% ) 设计缓存的颗粒度

2,排行榜: 游戏排名、社交(微博 抖音)

3,计数器应用: 访问量、播放量、下载量

4,社交网络:标签、共同的好友

5,消息队列(守护进程 Supervisor Yum): 普通队列、阻塞队列

6, 其它场景等

以上希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的官方群点击此处

redis版本说明:

Redis的偶数版为稳定版 奇数版为非稳定版

String:

存储的类型:数字、二进制安全(图片、音频、视频)

Set name winner ex|px 30 nx|xx

set age 23 ex 10 //10秒后过期 px 10000 毫秒过期

setnx gid 1 //不存在键gid时,返回1设置成功;存在的话失败0

set age 30 xx //存在键age时,返回1成功

EX seconds : 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。

PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。

NX : 只在键不存在时, 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value 。

XX : 只在键已经存在时, 才对键进行设置操作

获值命令:

get age //存在则返回value, 不存在返回nil

批量设值:

mset student zhangsan age 30

批量获取:

mget student age salary //返回zhangsna 30, salary为nil

注意:若没有mget命令,则要执行n次get命令

字符串内部编码:

Int: 8个字节长整数。字符串为整型

Embstr:<=39字节 字符串

Raw:>39字节

Hash:

哈希hash是一个string类型的field和value的映射表,hash特适合用于存储对象

命令 hset key field value

设值:hset user:1 name Winner //成功返回1,失败返回0

取值:hget user:1 name //返回Pack

删值:hdel user:1 age //返回删除的个数

计算个数:hset user:1 name Winner; hset user:1feature handsome;

hlen user:1 //返回2,user:1有两个属性值

批量设值:hmset user:2 name Winner age 18 sex man //返回OK

批量取值:hmget user:2 name age sex //返回三行:Pack 18 man

判断field是否存在:hexists user:2 name //若存在返回1,不存在返回0

获取所有field: hkeys user:2 // 返回name age sex三个field

获取user:2所有value:hvals user:2 // 返回Pack 18 man

获取user:2所有field与value:hgetall user:2 //name age sex Pack 18 man值

增加1:hincrby user:2 age 1 //age+1

hincrbyfloat user:2 age 2 //浮点型加2

List: 双向链表结构

数据的分为:标量、映射、序列

队列特点:先进先出

添加命令:

rpush Pack c b a //从右向左插入cba, 返回值3

lrange Pack 0 -1 lpush key c b a //从左到右获取列表所有元素 返回 c b a

linsert Pack before b teacher //从左向右插入cba

//在b之前插入teacher, after为之后,使用lrange Pack 0 -1 查看:c teacher b a

查找命令:

lrange key start end //索引下标特点:从左到右为0到N-1 -1代表最后一个

lindex Pack -1 //返回最右末尾a,-2返回b

llen Pack lpop Pack rpop james

Set:

指令:

zadd key score member [score member......]

zadd user:zan 200 Pack //Pack的点赞数1, 返回操作成功的条数1

zadd user:zan 200 Pack 120 Peter 100 Candy // 返回3

zadd test:1 nx 100 Pack //键test:1必须不存在,主用于添加

zadd test:1 xx incr 200 Pack //键test:1必须存在,主用于修改,此时为300

zadd test:1 xx ch incr -299 Pack //返回操作结果1,300-299=1

zrange test:1 0 -1 withscores //查看点赞(分数)与成员名

zcard test:1 //计算成员个数, 返回1

排名场景:

zadd user:3 200 Pack 120 Peter 100 Candy //先插入数据

zrange user:3 0 -1 withscores //先插入数据

zrank user:3 Pack //返回名次:第3名返回2,从0开始到2,共3名

zrevrank user:3 Pack

缓存击穿的情况:当一个请求访问一个热点Key,访问的过冲恰好失效,就会让请求走到数据库

解决方案:加锁。Swoole-->lock 文件锁 redis锁

缓存不失效 ,定点更新商品

缓存穿透:请求数据库访问根本不存在的数据

解决方案: 布隆过滤器

内存数据库问题:断电就丢失数据

持久化:

Rdb:全量复制,生成的是数据库快照

命令:config set dir /usr/local //设置rdb文件保存路径

备份:bgsave //将dump.rdb保存到usr/local下

恢复:将dump.rdb放到redis安装目录与redis.conf同级目录,重启redis即可

优点:

1,压缩后的二进制文件,适用于备份、全量复制,用于灾难恢复

2,加载RDB恢复数据远快于AOF方式

缺点:

1,无法做到实时持久化,每次都要创建子进程,频繁操作成本过高

2,保存后的二进制文件,存在老版本不兼容新版本rdb文件的问题

AOF:实时持久化,保存的Redis执行命令到文件中

设置appendonly yes;

将appendonly.aof 放到dir参数指定的目录;

启动Redis,Redis会自动加载appendonly.aof文件。

AOF的优缺点:

优点:在于支持秒级持久化、兼容性好,

缺点:文件大、恢复速度慢、对性能影响大

appendonly yes //启用aof持久化方式

# appendfsync always //每收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用

appendfsync everysec //每秒强制写入磁盘一次,性能和持久化方面做了折中,推荐

no-appendfsync-on-rewrite yes //正在导出rdb快照的过程中,要不要停止同步aof

auto-aof-rewrite-percentage 100 //aof文件大小比起上次重写时的大小,增长率100%时,重写

auto-aof-rewrite-min-size 64mb //aof文件,至少超过64M时,重写

加载顺序:AOF>RDB