一、需要学习的内容
-
redis是nosql的一种,为什么需要用redis,redis在真实项目中的使用场景
-
redis的常见数据类型 ----->有的类型用来实现微信“周围的人”
-
redis持久化
-
redis如何实现事务操作(区别于mysql的事务操作)
-
redis主从复制 (mysql 可以用binlog日志文件实现主从复制)
-
哨兵模式
-
缓存穿透
-
缓存雪崩
-
现在都用springboot集成redis
二、单机mysql的演进——为什么需要nosql?
2.1 单机mysql的问题
之前数据量小的时候,我们用一个mysql就可以满足用户存储数据、增删改查的要求。
现在是大数据时代,mysql的优势在于海量数据的存储,但是海量数据的增删改查就显得力不从心。
单机mysql(只有一个mysql服务器)存在的问题:
(1)只有一台机器存所有用户的数据,存不下了!=====>需要mysql服务器集群
(2)所有用户的读、写都访问这台mysql服务器,访问量太大了,一个请求要响应10s这哪个用户遭得住 =====>需要主从服务器
(3)数据的多样性。图片、视频这样的数据还有微博热搜、音乐热榜这样每天实时滚动的数据不适合用mysql存储。====>需要nosql
2.2 演进过程
首先我们准备3个mysql服务器,他们3个的内容是同步的。1号和3号负责用户的读操作(因为80%的用户请求都是读),而2号负责写操作,并把更改的结果同步到1和3(主从复制,2号服务器叫主服务器,1号和3号叫从服务器)。之前我们增删改查都逮着一个服务器可劲薅,服务器的响应时间就会变长,现在我们一个主服务器用来写,两个从服务器用来读,这样就能提高响应时间,也就是系统的可用性。
又有一个问题:如果张三刚从1号服务器读完了一行数据,李四又要读同一行数据,如果不加缓存的话,就要连续读两次MySQL服务器,所以,缓存的作用就出现了!试想如果是双十一期间,成千上万的人同时点击一个链接呢?都去访问MySQL服务器吗?挤爆它吗?nonono,这些热点数据会被提前放到redis当中,大家在双十一当天访问的都是redis中的数据。
还有问题,大学有1万个学生,可以都存在一张学生表里。但是淘宝有7亿个用户,我能都存到一张表里吗?No!我们要分库分表,这就出现了mysql集群。
还有问题!网站的资源越来越多样化,mysql这种关系型数据库只能存关系型数据,那图片、音视频、滚动热搜这种资源怎么办呢?nosql!
以2011年阿里巴巴为例分析数据架构,可以简单理解为,一个淘宝页面,都用到了哪些数据库,好多啊。。
此外,还有负载均衡(Nginx),服务器的分布式、服务器之前如何通过中间件通信、如何保证分布式ID的唯一等等一系列需要考虑的问题。。。。。
三、redis概述
-
redis全称:remote dictionary server远程字典服务。既然是字典,那么肯定与我们的“中华字典”有相似之处。其实redis里就是key-value的模式,根据key去查value,就好比我们根据拼音或者偏旁部首去查文字一样。然而这个value又有很多形式,可以是String,可以是一整个集合list,map、set。
-
redis的快的原因有好多,
-
最主要的是完全运行在内存里,内存的速度当然比MySQL这种存在磁盘里的快多了
-
第二个原因是Redis是单线程的,没有上下文切换带来的消耗
-
再就是IO多路复用,可以同时受理多个连接请求,select,epoll什么玩意的;
-
第四是因为它是key-value型数据库,找到一个数据的时间复杂度为仅为O(1)。
-
第五可有可无哈哈哈,因为redis是用C写的,自然会快一些。
-
-
其实redis一共有3个功能:
-
数据库
-
缓存
-
消息中间件(可以实现简单的发布和订阅,如果更复杂的场景肯定要用rocketmq和卡夫卡这种专业的去做)
但是人们总误以为redis就等于缓存。就和误以为maven只是一个导包工具一样,其实maven是一个功能很强大的构建工具。
-
开源、C语言编写的、key-value数据库
-
官方给出的读的速度:11万 次/s(超快!), 写的速度:8万次/s
-
默认有16个数据库db0~db15,默认连接的是db0。
-
在redis命令行里少用中文(不用中文),会变成一些转义的东西!
-
之后不会单独使用redis客户端去操作redis,一律都在springboot中。
3.1 redis能干嘛
-
高速缓存:作为MySQL的cache。有一个问题,我们想访问的数据是MySQL的数据,但是有了redis以后访问的是redis的数据,万一二者不一致怎么办? expire设置过期时间!
-
持久化(从内存到硬盘,rdb,aof)
-
作为数据库实现内存存储
-
订阅发布 (充当简单的消息队列)
-
地图信息分析(“附近的人”)
-
计时器、计数器(“公众号浏览量”)
-
秒杀必须用redis,用其他的都得完蛋:比如双十一零点的时候,淘宝的数据一定提前从MySQL拷贝到了redis里,没有redis只用MySQL的话,淘宝一秒崩
官方不建议在Windows下使用redis!会出现兼容性问题。
3.2 为什么redis的端口号是6379?
作者是粉丝
3.3 高频问题
为什么redis是单线程
因为redis的设计思想是基于内存的,“如果我的数据全都在内存里,我单线程的去操作就是效率最高的”。这个问题等同于“为什么不涉及多线程”?因为多线程会涉及到上下文在内存中的切换,还不如单线程更快。(也有可能作者分别设计了单线程和多线程,然后进行qps测试,发现单线程效率更高)
为什么redis是单线程的还这么快?
对于内存系统来说,没有上下文的切换效率就是最高的。多线程会涉及到上下文在内存中的切换会耗时,还不如单线程更快。
增加CPU核数会提高redis执行速度吗?
不会,因为redis是单线程的,redis的运行速度只和内存大小(以及网络带宽)有关。和CPU的核数无关哦。但是和CPU的频数依然是有关的,因为redis毕竟也是一个用C语言写的程序,既然是程序,底层就是一条条的微指令,一个微指令又由很多微命令组成,一个CPU时钟周期执行一个微命令,频数越大,时钟周期越短自然程序执行越快,所以redis的执行速度当然和CPU的性能有关。
PS :这里我们一直在强调的单线程,只是在处理我们的一个网络请求的时候只有一个线程来处理,一个正式的Redis Server运行的时候肯定是不止一个线程的,因为会有多个用户的网络请求呀(IO多路复用),也可能会出现多个线程同时操作一个redis数据的情况,也是需要加锁操作的。
这里需要大家明确的注意一下。例如Redis进行持久化的时候会以子进程或者子线程的方式执行。
四、常用命令
-
select 切换数据库
-
DBSIZE查看【当前】数据库大小
-
flushall 删除所有数据库中的所有数据
-
flushdb 删除当前库的数据
-
keys *: 查看当前数据库键值的个数
-
ping :返回“PONG”表示目前是cli是连接上redis-server的状态
-
EXISTS 键值:返回“1”表示键值存在,“0”不存在
-
move 键值 1: 命令中的“1”表示当前数据库,是必写的
9、clear:清屏