文章目录
- Redis介绍
- 初步了解分布式系统
- 环境搭建
- 通用命令
- 常用数据结构
- 关于单线程模型
Redis介绍
Redis的官方文档:Redis – The Real-time Data Platform
–如果有不知道的东西(比如属性)的话,就去这查就行了
–或者去看redis源码也行
Redis最主要的作用是存储数据(在内存中存储数据)–也就是作为数据库使用
跟MySQL的对比:
MySQL最大的问题是访问的速度慢(因为是存在硬盘里面的),Redis会快很多
Redis相较于MySQL的话,存储空间会小很多
在业务中一般都是使用的二八原则:就是大概百分之80的用户请求只会访问百分之20的热点数据
–那就是把这百分之20的热点数据预先存到Redis里面,MySQL存所有数据(但是要注意Redis跟MySQL之间数据同步问题)
–而且Redis会给这个key设置一个过期时间+在Redis内存不足时会有淘汰策略
Redis只有在分布式系统中才能发挥作用;如果是单机程序的话,直接通过变量进行数据存储会更好
Redis是基于网络,把自己内存中的变量给别的进程(不同主机也行)使用
Redis的默认端口号是6379
Redis的一些特性: 1.在内存中存储数据
MySQL主要是通过表的方式存储组织数据的(属于关系型数据库)
Redis主要是通过键值对的方式来存储组织数据的(属于非关系型数据库)–Redis的键值对的key都是string value的话类型有很多,Redis自身的键值对是通过哈希表的方式来组织的
2.持久化
Redis平时用内存读写,同时也会把内存里的数据定期或者实时写到硬盘;所以如果Redis重启了,会在重启时加载硬盘中的备份数据,让Redis的内存恢复到重启前的状态
3.支持集群
也就是可以把多台Redis服务器连成一个整体来对外提供服务(每个Redis存储数据的一部分这样)
4.高可用
Redis支持主从复制和自动故障转移,所以Redis是高可用的
主从复制:主节点实时同步数据给从节点,让主从节点的数据完全一致
自动故障转移:主节点挂了,自动把从节点升成新的主节点
5.速度快(相较于MySQL)
–Redis采用多线程一般是不会提高效率的,因为多线程提高效率的前提是处理的是CPU密集型的任务;但是Redis的核心任务并不吃CPU
6.客户端语言多
Redis的应用场景:
1.作为数据库(比如搜索引擎对性能要求比较高)–但是这样搞就很吃硬件了
2.用MySQL存数据,然后二八原则把热点数据在redis里面也存一份(这个最常用)
3.作为消息队列(不是Linux进程间通信的消息队列)
这里的消息队列是在分布式系统中,服务器和服务器之间使用生产者消费者模型–作用:解耦合和削峰填谷
–如果在当前场景中(已有redis的话),对于消息队列的功能的依赖不多且不想引入额外的依赖,就用Redis
引申:Redis6.0开始增加了权限控制机制:
就是给Redis所有命令打上标签,管理员给用户分配权限时,可以直接授予/禁止某一个标签或单独控制某个命令
初步了解分布式系统
分布式系统其实就是多个服务器分工合作
–但是引入分布式系统的话,系统的复杂程度会大大提高,出bug的概率也会变高
单机架构的话就是一个服务器完成所有的工作
如果服务器不够用了,应该怎么处理: 1.开源(最省事,就是直接增加硬件资源) 2.节流(就是限制请求次数)
–对整体的话,还可以进行微服务的那种拆分
–对数据库服务器的拆分方法是分库分表
而且一般来说,较大的项目,应用服务器跟数据库服务器是分开来的,不混着用:
因为应用服务器吃CPU和内存,数据库服务器吃硬盘容量(机械硬盘 便宜+慢 ;固态硬盘 贵+快)
引申:应用服务器接收到的请求是由负载均衡器(又是单独的服务器)分配的
而且数据库服务器还分主数据库和从数据库(一般是一主多从)以及读写分离
主数据库只处理写操作,数据修改完实时同步给所有从数据库 从数据库只处理读操作
引申:一般的业务都是读多写少
Redis用于缓存服务器,来帮数据库服务器分担承重(专门多存储一份访问量高的数据,也是只读)
拆分成微服务的优缺:
缺点:系统的性能下降(因为更加依赖网络通信了,网络通信多半比硬盘读写慢);系统复杂程度提高
优点:更方便功能的复用;能够给不同服务进行不同的部署;解决了大项目人效问题
如果负载均衡器把一个用户的不同请求打到不同服务器上,没收到登录请求的服务器不认识咋办
解决方法:
1.把会话数据单独拿出来放到一组独立的机器上存储(使用redis的方式)–这个是最优解
2.想办法让负载均衡器把同一个用户的请求始终打在同一个机器上(也就是不轮询来分配请求,而是根据useid这些来分配请求给机器)
项目的演化步骤一般是:单机架构->数据库和应用分离->负载均衡+集群->读写分离+数据库主从结构->引入缓存(单独存一份热数据)->分库分表->引入微服务
一些概念的引入:
应用/系统:一个应用就是一个或者一组服务器程序
模块/组件:一个应用里面有多个功能;每个独立的功能就是一个模块/组件
分布式:物理上的多个主机/服务器协同配合完成一系统工作
集群:逻辑上的多个主机/服务器协同配合完成一系统工作 –集群还有个优点就是里面的某个主机挂了,其他主机还能承担服务
–这样就提高了整个系统的可用性
主/从:分布式系统里的典型结构(多个服务器节点里面一个是主,其他的是从;从节点的数据是由主节点同步过去的)
中间件:与业务无关的服务,属于是起到辅助功能(比如:数据库、缓存、消息队列)
可用性:系统整体可用的时间比上总的时间 –这个是一个系统最应该重视的
响应时长:这个是用来衡量服务器性能的标准
吞吐和并发:是衡量系统处理请求的能力以及衡量性能的一种方式
环境搭建
这里介绍的是centos下的redis的环境搭建,等使用Redis集群相关的功能时才需要用到Docker
Redis官方版本只支持Linux的,windows那个是windows自己维护的第三方分支
自己这里使用的Redis是5.0版本的
Redis的默认端口是6379
如果是Centos8,yum源默认的redis版本是5系列
安装指令:yum install -y redis
然后修改redis的配置文件(让他支持远程连接):/etc/redis.conf里面改成bind 0.0.0.0和protected-mode no
启动redis:systemctl start redis
停止redis进程:systemctl stop redis 重启redis服务:systemctl restart redis
/etc/redis-sentinel.conf是 Redis Sentinel 的配置文件
/etc/redis.conf是Redis 服务器的配置文件
/var/lib/redis/:Redis 持久化⽣产的 RDB 和 AOF 文件都默认生成于该目录下
/var/log/redis/:里面存的是存 Redis 运行期间生产的日志文件
如果是Centos7,yum源默认的redis版本是3系列
–那就需要先安装额外的软件源了 yum install centos-release-scl-rh 然后再yum install rh-redis5-redis
此外,还需要创建符号链接(因为默认安装路径藏得太深了)和修改配置文件
创建符号链接:
针对可执⾏程序设置符号链接
cd /usr/bin
ln -s /opt/rh/rh-redis5/root/usr/bin/redis-server ./redis-server
ln -s /opt/rh/rh-redis5/root/usr/bin/redis-sentinel ./redis-sentinel
ln -s /opt/rh/rh-redis5/root/usr/bin/redis-cli ./redis-cli
针对配置⽂件设置符号链接
cd /etc/
ln -s /etc/opt/rh/rh-redis5/ ./redis
修改配置文件:
设置ip地址:bind 0.0.0.0
关闭保护模式: protected-mode no
启动守护进程:daemonize yes
设置工作目录:mkdir -p /var/lib/redis dir /var/lib/redis
设置日志目录:mkdir -p /var/log/redis/ logfile /var/log/redis/redis-server.log
启动Redis的指令:redis-server /etc/redis/redis.conf
杀死Redis进程的指令:先查pidps aux | grep redis 或者 netstat -anp | grep redis 然后用kill的方式杀死redis进程
关于redis客户端:(redis跟mysql一样,也是一个客户端,服务器结构的程序,服务器负责存储和管理数据,客户端就是跟服务器请求、响应这样获取数据)
命令行客户端有两种方式连接redis服务器:
1.交互式方式(自己常用)
redis-cli -h 127.0.0.1 -p 6379连接到redis服务,然后后续直接输指令就行
但是上面这个指令可以简化成redis -cli
2.命令方式
redis–cli –h 127.0.0.1 –p 6379 指令
但是工作中,一般都是用redis的C语言api这种来操控redis
注意:加上–raw的话,redis客户端会自动把二进制数据尝试翻译
通用命令
Redis里面的命令不区分大小写!
set:把key和value存进去
get:根据key来取value,如果当前key不存在,会返回nil
这里的key和value加''和"" 和 啥也不加的效果是一样的(如果key或value里面有空格的话就必须要单或双引号)
–每次只能set或者get一个!
keys: 语法:keys pattern eg:keys a??
pattern支持的通配符 eg:
?-匹配任意一个字符
*-匹配任意长度的字符
[abc]-这一个位置只匹配一个字符&&只能匹配到a或b或c
[^e]-这一个位置只匹配一个字符&&只有e匹配不了,其他的都能匹配
[a-e]:这一个位置只匹配一个字符&&只能a,b,c,d,e
时间复杂度是O(N),返回值是匹配pattern的所有key
–一般在生产环境中是禁止使用keys(因为redis是单线程服务器,执行比如keys*的时间会很长,容易阻塞;然后请求就都要mysql处理了,mysql就容易挂,整个系统就容易瘫痪)
exists:语法exists key1 [key2…]
时间复杂度:O(1),返回值:key1-key…中存在的个数
del: 语法:del key1 [key2…]
时间复杂度:O(1),返回值:key1-key…中被删除掉的个数
–redis作为缓存的话,如果key误删了几个,一般问题不大;如果删除的数据多了,大部分请求就会打到mysql上,mysql就容易挂
expire:语法expire key seconds 为指定的key添加秒级的过期时间 eg:expire key 10
时间复杂度:O(1) 返回值:设置成功返回1,设置失败返回0
–pexpire是为指定的key添加毫秒级的过期时间(用法跟expire一样)
ttl:语法ttl key 获取指定key的过期时间(秒级)
时间复杂度:O(1) 返回值:剩余过期时间(-1的话表示没有关联过期时间,-2表示key不存在)
–pttl是获取指定的key的过期时间(毫秒级),用法跟ttl一样
这个ttl跟ip协议报头的TTL不一样,ip中的TTL是用次数衡量过期的
type:语法type key
时间复杂度:O(1) 返回值:key对应的数据类型;key如果不存在的话,返回none
flushall [ASYNC | SYNC]:删除所有数据库中所有的key flushdb [ASYNC | SYNC]:删除当前数据库中所有的key
–ASYNC是异步删除(就是删除任务扔给后台线程,主线程立刻返回去处理业务请求);SYNC是同步请求
–Redis6.2及以上默认是用的异步,其余版本默认用的是同步
Redis数据库管理相关的命令:
Redis中的数据库是现成的,用户不能创建新的数据库,也不能删除已有的数据库
–默认的话,Redis是会提供16个数据库(编号是0-15)
–但是事实上redis很少会关注数据库层面,一般都是用0号数据库就行了
切换数据库:select 数据库编号 –如果不切换的话,默认是0号数据库
获取当前数据库中key的个数:dbsize 时间复杂度是O(1)
exists key1 key2 和exists key1 exists key2的区别:
第二种分开的写法会产生更多轮次的网络通信,效率更低,成本更高
–所以redis的很多命令都是支持一次就能操作多个key的
引申: 未来工作中的几种环境介绍
办公环境:比如笔记本
开发环境:有时跟办公环境是一样的;有时是一个单独的服务器(后端基本是这种)
测试环境:测试工程师使用的
–上面的统称线下环境(外界用户访问不到的)
线上环境或者生产环境(外界用户能访问的到的):如果这部分出问题,一定会对用户的使用产生影响–操作时一定要谨慎再谨慎!
Redis的过期策略是怎么实现的:
1.定期删除 2.惰性删除 3.内存淘汰策略
就是每次抽取一部分数据验证过期时间+访问到key,如果key过期了,就删除,然后返回nil+内存淘汰策略
注意:抽取数据验证的过程要快,不然单线程的redis会阻塞的
–Redis中并没有采取定时器的方式去实现过期key的删除!!!
引申:高效定时器的实现思路:
1.基于优先级队列或者堆的实现思路
就是按照过期时间越早,优先级越高的形式来进出;然后需要单独一个线程去检查队首元素是否过期
(不能检查的太频繁! 可以搞个休眠时间,到到点再唤醒这个线程–如果有新任务来了的话,就提前唤醒一次)
2.基于时间轮实现的定时器
就是把时间分成很多小段,每个小段上挂一个链表,链表里面代表这个时间点需要要执行的任务
–时间轮一共有多少格子以及每个格子是多少时间是根据实际业务而定的
常用数据结构
Redis常用的五种数据结构有:string(字符串)、hash(哈希)、list(列表,相当于双端队列)、set(集合)、zset(有序集合,会按其中一个元素进行排序)
同一个数据类型,它背后的编码方式可能是不同的,会根据特定场景优化

查询某个key具体内部编码的指令:object encoding key名
常考面试题:
redis虽然是单线程模型,为什么效率很高,速度也很快?(相较于mysql,oracle,sql server这些数据库)
1.redis访问的是内存,数据库访问的是硬盘
2.redis的核心功能比数据库的核心功能简单(数据库对于数据的插入删除查询这些都有更复杂的功能支持)
3.单线程模型避免了一些不必要的线程竞争的开销
4.redis处理网络IO时,使用了epoll那样的IO多路复用机制
关于单线程模型
Redis单线程模型指的是redis只使用一个线程去处理所有的命令请求,但是redis服务器进程内部有多个进程在处理网络IO
redis能使用单线程模型做好事情的原因主要在于redis的核心业务逻辑都是短平快的,不太消耗cpu资源,所以也就不太吃多核
但是redis是单线程模型有个很大的弊端:redis要小心某个操作占用时间长会阻塞其他命令的执行
网硕互联帮助中心



评论前必须登录!
注册