Redis一个开源的基于键值对(Key-Value)NoSQL数据库。使用ANSI C语言编写、支持网络、基于内存但支持持久化。性能优秀,并提供多种语言的API。
我们要首先理解一点,我们把Redis称为KV数据库,键值对数据库,那就可以把Redis内部的存储视为存在着一个巨大的Map,对Map的操作无非就是get和put,然后通过key操作这个key所对应的value,而这个value的类型可以多种多样,也就是Redis为我们提供的那些数据结构,比如字符串(String)、哈希(Hash)等等。
Redis就这么简单吗?这些年李老师的经历,我发现,很多技术人都有一个误区,那就是,只关注零散的技术点,没有建立起一套完整的知识框架,缺乏系统观,但是系统观其实是至关重要的。从某种程度上说,在解决问题时,拥有了系统观,就意味着你能有依据、有章法地定位和解决问题。
那么,如何高效地形成系统观呢?本质上就是,Redis 的知识都包括什么呢?简单来说,就是“两大维度,三大主线”
两大维度:应用维度、底层原理维度
我们知道,缓存和集群是Redis 的两大广泛的应用场景。同时Redis 丰富的数据模型,就导致它有很多零碎的应用场景,很多很杂。而且,还有一些问题隐藏得比较深,只有特定的业务场景下(比如亿级访问压力场景)才会出现,所以同时还必须精通Redis的数据结构。
Redis应用场景
1.缓存
缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力。Redis提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。可以这么说,一个合理的缓存设计能够为一个网站的稳定保驾护航。
一般MySQL数据库写的并发是600/s,读的2000/s,对于大型互联网项目的百万并发,根本扛不住,Redis的官方显示Redis能够单台达到10W+/s的并发。
2.排行榜系统
排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。
3.计数器应用
计数器在网站中的作用至关重要,例如视频网站有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。
4.社交网络
赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。
5.消息队列系统
消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功能基本可以满足。这个是Redis的作者参考了Kafka做的拓展。
三大主线:高性能、高可靠和高可扩展
高性能:包括线程模型、数据结构、持久化、网络框架;高可靠:包括主从复制、哨兵机制;高可扩:包括数据分片、负载均衡。
因为Redis的应用场景非常多,不同的公司有不同的玩法,但如何不掌握三高这条主线的话,你会遇到以下问题:
1、数据结构的复杂度、跨 CPU 核的访问会导致CPU飙升的问题
2、主从同步和 AOF 的内存竞争,这些会导致内存问题
3、在 SSD 上做快照的性能抖动,这些会导致存储持久化的问题
4、多实例时的异常网络丢包的问题
在Redis的版本计划中,版本号第二位为奇数,为非稳定版本,如2.7、2.9、3.1;版本号第二为偶数,为稳定版本如2.6、2.8、3.0;一般来说当前奇数版本是下一个稳定版本的开发版本,如2.9是3.0的开发版本。
同时Redis的安装也非常简单,到Redis的官网(Download | Redis),下载对应的版本,简单几个命令安装即可。
wget https://download.redis.io/releases/redis-6.2.7.tar.gz
tar xzf redis-6.2.7.tar.gz
cd redis-6.2.7/
make
安装后源码和执行目录会混在一起,为了方便,我做了一次install
make install PREFIX=/home/lijin/redis/redis
因为Redis的安装一般来说对于系统依赖很少,只依赖了Linux系统基本的类库,所以安装很少出问题
安装常见问题
如果执行make命令报错:cc 未找到命令,原因是虚拟机系统中缺少gcc,执行下面命令安装gcc:
yum -y install gcc automake autoconf libtool make
如果执行make命令报错:致命错误:jemalloc/jemalloc.h: 没有那个文件或目录,则需要在make指定分配器为libc。执行下面命令即可正常编译:
make MALLOC=libc
Redis编译完成后,会生成几个可执行文件,这些文件各有各的作用,我们现在先简单了解下,后面的课程会陆续说到和使用这些可执行文件。
一般来说redis-server和redis-cli这些平时用得最多。
Redis有三种方法启动Redis:默认配置、带参数启动、配置文件启动。
使用Redis的默认配置来启动,在bin目录下直接输入 ./redis-server
可以看到直接使用redis-server启动Redis后,会打印出一些日志,通过日志可以看到一些信息:
当前的Redis版本的是64位的6.2.7,默认端口是6379。Redis建议要使用配置文件来启动。
因为直接启动无法自定义配置,所以这种方式是不会在生产环境中使用的。
redis-server加上要修改配置名和值(可以是多对),没有设置的配置将使用默认配置,例如:如果要用6380作为端口启动Redis,那么可以执行:
./redis-server --port 6380
这种方式一般我们也用得比较少。
配置文件是我们启动的最多的模式,配置文件安装目录中有
复制过来
改一下权限
通过配置文件来启动
./redis-server ../conf/redis.conf
注意:这里对配置文件使用了相对路径,绝对路径也是可以的。
同时配置文件的方式可以方便我们改端口,改配置,增加密码等。
打开注释,设置为自己的密码,重启即可
Redis服务启动完成后,就可以使用redis-cli连接和操作Redis服务。redis-cli可以使用两种方式连接Redis服务器。
1、单次操作
用redis-cli -hip {host} -p{port} {command}就可以直接得到命令的返回结果,例如:
那么下一次要操作redis,还需要再通过redis-cli。
2、命令行操作
通过redis-cli -h (host}-p {port}的方式连接到Redis服务,之后所有的操作都是通过控制台进行,例如:
我们没有写-h参数,那么默认连接127.0.0.1;如果不写-p,那么默认6379端口,也就是说如果-h和-p都没写就是连接127.0.0.1:6379这个 Redis实例。
Redis提供了shutdown命令来停止Redis服务,例如我们目前已经启动的Redis服务,可以执行:
./redis-cli -p 6379 shutdown
redis服务端将会显示:
除了可以通过shutdown命令关闭Redis服务以外,还可以通过kill进程号的方式关闭掉Redis,但是强烈不建议使用kill -9强制杀死Redis服务,不但不会做持久化操作,还会造成缓冲区等资源不能被优雅关闭,极端情况会造成AOF和复制丢失数据的情况。如果是集群,还容易丢失数据。
同样还可以在命令行中执行shutdown指令
shutdown还有一个参数,代表是否在关闭Redis前,生成持久化文件,缺省是save,生成持久化文件,如果是nosave则不生成持久化文件
对于键值数据库而言,基本的数据模型是 key-value 模型,Redis 支持的 value 类型包括了 String、哈希表、列表、集合等,而Memcached支持的 value 类型仅为 String 类型,所以Redis 能够在实际业务场景中得到广泛的应用,就是得益于支持多样化类型的 value。
Redis里面有16个库,但是Redis的分库功能没啥意义(默认就是0号库,尤其是集群操作的时候),我们一般都是默认使用0号库进行操作。
在了解Rediskey-value 模型之前,Redis的有一些全局命令,需要我们提前了解。
keys命令
keys *
keys L*
查看所有键(支持通配符):
但是这个命令请慎用,因为keys命令要把所有的key-value对全部拉出去,如果生产环境的键值对特别多的话,会对Redis的性能有很大的影响,推荐使用dbsize。
keys命令会遍历所有键,所以它的时间复杂度是o(n),当Redis保存了大量键时线上环境禁止使用keys命令。
dbsize命令
dbsize命令会返回当前数据库中键的总数。
dbsize命令在计算键总数时不会遍历所有键,而是直接获取 Redis内置的键总数变量,所以dbsize命令的时间复杂度是O(1)。
exists
检查键是否存在,存在返回1,不存在返回0。
del
删除键,无论值是什么数据结构类型,del命令都可以将其删除。返回删除键个数,删除不存在键返回0。同时del命令可以支持删除多个键。
键过期
expire
Redis支持对键添加过期时间,当超过过期时间后,会自动删除键,时间单位秒。
ttl命令会返回键的剩余过期时间,它有3种返回值:
大于等于0的整数:键剩余的过期时间。
-1:键没设置过期时间。
-2:键不存在
除了expire、ttl命令以外,Redis还提供了expireat、pexpire,pexpireat、pttl、persist等一系列命令。
expireat keytimestamp: 键在秒级时间截timestamp后过期。
ttl命令和pttl都可以查询键的剩余过期时间,但是pttl精度更高可以达到毫秒级别,有3种返回值:
大于等于0的整数:键剩余的过期时间(ttl是秒,pttl是毫秒)。
-1:键没有设置过期时间。
-2:键不存在。
pexpire keymilliseconds:键在milliseconds毫秒后过期。
pexpireat key