目录
Redis简介
什么是redis?
Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的基于内存的数据存储系统,可以用作数据库缓存和消息队列等各种场景。
与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。除此之外,Redis支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。
安装,运行Redis
直接通过官方网站进行安装Redis
运行Redis:
redis-server.exe redis.windows.conf
Redis的优点:
Redis的优点
- 性能及高
- 数据类型丰富,单键值对最大支持512M大小的数据
- 简单易用,支持所有主流编程语言
- 支持数据持久化、主从复制、哨兵模式等高可用特性
Redis为什么这么快?
- 使用虚拟内存机制
Redis 的 VM (虚拟内存)机制就是暂时把不经常访问的数据(冷数据)从内存交换到磁盘中,从而腾出宝贵的内存空间用于其它需要访问的数据(热数据)。通过 VM 功能可以实现冷热数据分离,使热数据仍在内存中、冷数据保存到磁盘。这样就可以避免因为内存不足而造成访问速度下降的问题。
- 支持多种数据类型
- 基于内存存储实现
内存读写是比在磁盘快很多的,Redis基于内存存储实现的数据库,相对于数据存在磁盘的MySQL数据库,省去磁盘I/O的消耗。
Redis的数据结构类型
Redis的基本数据结构
- String(字符串)
- Hash(哈希)
- List(列表)
- Set(集合)
- zset(有序集合)
特殊的数据结构类型
- Geospatial
- Hyperloglog
- Bitmap
字符串String
设置值
Redis中的数据是以键值对的形式存储的,在设置值的时候需要指定一个键和一个值,键和值之间使用空格来分隔
SET name xiaom
SETNX命令:只有当键不存在时才设置键的值,如果键已经存在则SETNX命令不做任何动作
查看值
可以使用get命令来查看我们设置的值:
GET name
注意:
- Redis中的键是区分大小写的
- Redis中默认都是使用字符串来存储数据的,而且是二进制安全的
- Redis中的键和值都是以二进制存储的,默认不支持中文。如果要查看中文的数据,则需要在登录的时候加上"--raw"表示以原始的形式来显示内容。
列表**(List)**
列表(List):一般用来存储和操作一组有顺序的数据,和数组的概念比较类似,可以使用LPUSH或者RPUSH命令来将元素添加到列表的头部或尾部。
获取列表内容需要使用LRANGE命令;格式:LRANGE+表示列表名称的键+起始位置+结束位置(0 -1:获取从第一个到最后一个元素)
由于LPUSH命令会把后面参数中的元素按照从左到右的顺序依次添加到列表的头部,所以最后添加的元素在遍历时就会被排在最前面。
使用RPUSH命令从尾部添加元素
LPOP命令,从列表的头部删除元素;RPOP命令,从列表的尾部删除元素
LPOP/RPOP+列表名称+要删除的元素个数-->一次性删除多个元素
查看列表长度:LLEN
删除列表中指定范围以外的元素:LTRIM-->LTRIM letter 1 3:删除列表中第1到第3以外的元素
集合(Set)
set是一种无序集合,它和列表的区别在于列表中的元素都是可以重复的,而set中的元素是不能重复的
向Set中添加一个命令:SADD+集合名称+要添加的值
查看Set中的元素:SMEMBERS
判断某元素是否在集合中:SISMEMBER
删除集合中的元素:SREM
集合中的运算
SINTER SUNION SDIFF
有序集合(zset)
zset与集合的区别是有序集合的每个元素都会关联一个浮点类型的分数,然后按照这个分数来对集合中的元素进行从小到大的排序。有序集合的元素是唯一的,但是分数是可以重复的。
在有序集合中添加元素:ZADD
查看有序集合中的元素:ZRANGE+集合名称+起始位置+结束位置。想要输出分数则在命令的最后面加上一个WITHSCORES
查看某个元素的分数:ZSCORE+集合名称+元素名
查看某个元素的排名:ZPANK+集合名称+元素名
将排名反转:ZREVRANK
哈希(Hash)
哈希是一个字符类型的字段和值的映射表,简单来说就是一个键值对的集合
在哈希中添加一个键值对:HSET
删除哈希中的一个键值对:HDEL
查看哈希中的某一个键值对:HGET
查看哈希中的所有键值对:HGETALL
查看哈希中是否存在某个键值对:HEXISTS
发布订阅模式
可以通过PUBLISH命令将消息发送到指定的频道,然后通过SUBSCRIBE命令来订阅这个频道,这样就可以接受到这个频道的消息了。
消息队列Stream
Stream是Redis5.0版本中引入的一个新的数据结构,是一个轻量级的消息队列,可以用来解决发布订阅功能的一些局限性,如消息无法持久化,无法记录历史消息等。
向Stream中添加消息:XADD
查看Stream中消息的数量:XLEN
查看消息的详细内容:XRANGE(可以使用-和+表示所有的消息来打印所有消息的详细内容)
删除消息:XDEL/XTRIM(XTRIM+队列名称+MAXLEN 0表示删除所有的消息)返回值为删除的消息的数量
读取消息:XREAD+COUNT+n(表示一次读取n条消息)+BLOCK+t(BLOCK表示如果没有消息就阻塞t毫秒)+STREAMS+队列名称+起始位置。消息可以重复读取
可以给消息队列添加一个消费者组来容纳消费者。Redis允许消息队列对应的消费者组里面的消费者同时XREAD消息
创建消费者组:XGROUP CREATE +消息队列+消费者组名称+ID
查看消费者组的信息:XINFO GROUPS+消息队列名称
向消费者组中添加消费者:XGROUP CREATECONSUMER +消息队列名称+组名+消费者名称
地理空间(Geospatial)
Geospatial提供了一种存储地理位置信息的数据结构,同时支持对地理位置进行各种计算操作
添加地理位置信息:GEOADD + 名字 + 经纬度 + 城市名称
获取某个位置的经纬度:GEOPOS + 名字 + 城市名称
计算两个位置之间的距离:GEODIST(默认单位是米)+KM将单位换算为千米
搜索指定范围内的成员并返回(可以以成员的位置,某个经纬度为中心按照圆形或矩形进行查找):GEOSEARCH
距离上海300千米以内的城市:GEOSEARCH city FROMMEMBER shanghai BYRADIUS 300KM[可以使用BYBOX实现矩形范围查找]
HyperLogLog
HyperLogLog是一种用来做基数统计的算法,原理是使用随机算法来计算,通过牺牲一定的精确度来换取更小的内存消耗。优点是占用内存小,缺点是会有一定的误差,适合做一些对精确度要求不高且数据量非常大的统计工作。
基数:如果集合中的每一个元素都是唯一且不重复的,那么这个集合的基数就是集合中元素的个数。
添加元素:PFADD
查看基数:PFCOUNT
将多个HyperLogLog合并:PFMERGE
位图(Bitmap)
位图是字符串类型的扩展,可以使用一个String类型来模拟一个Bit数组,数组的下标就是偏移量,值只有0和1,也支持一些位运算
设置某个偏移量的值:SETBIT
获取某个偏移量的值:GETBIT
统计某一个key的值里面有多少个bit是1:BITCOUNT
获取某个key里面第一个出现0或者1的位置:BITPOS
也可以直接使用字符串的命令来设置它的值
Redis的过期策略
设置过期时间
在设置值时,可以给它设置一个过期时间,我们可以使用EXPIRE命令或SETEX命令来设置过期时间:
EXPIRE name 10//设置name的过期时间为10秒
SETEX name 5 xiaom//设置name的过期时间为5秒
可以使用TTL(Time To Live)命令来查看键值对的过期时间,表示该键还有多长时间过期。(没有设置过期时间则输出-1);
当键值对过期后,使用GET命令就不会有输出值,使用KEYS命令也看不到该键。那么在键值对过期之后,redis是如何处理的呢?
Redis同时使用惰性过期和定期过期两种过期策略。
所谓惰性过期,即当主动访问一个key时,才会判断该key是否已经过期,过期则清除,而定期过期是每隔一定时间,会扫描一定数量的key,并清除其中已经过期的key
Redis事务和持久化
Redis事务
Redis支持事务,也就是说可以在一次请求中执行多个命令。Redis中的事务主要是通过MULTI和EXEC这两个命令来实现的。
MULTI命令用来开启一个事务,事务开启后,所有的命令就都会被放入到一个队列中,最后通过一个EXEC命令来执行事务中的所有命令。
在Redis中事务并不能保证所有的命令都会执行成功,它的执行结果取决于事务中的命令。
- 在发送EXEC命令之前,所有的命令都会被放入到一个队列中缓存起来,不会立即执行。
- 在收到EXEC命令之后,事务开始执行,事务中的任何一个命令执行失败,其他命令依然会被执行。
- 在事务执行的过程中,其他客户端提交的命令请求,并不会被插入到事务的执行命令序列中。
Redis持久化
Redis中的持久化主要有两种方式:一种是RDB(Redis Database)方式,另一种是AOF(Append Only File)方式
RDB:在指定时间间隔内将内存中的数据快照写入磁盘,是某一个时间点上数据的完整副本,可以通过配置文件中的save参数来配置。
由于生产环境中我们为Redis开辟的内存区域一般都比较大,那么内存中的数据同步到硬盘这个过程就会持续比较长的时间,而这段时间里Redis都是处于一个阻塞的状态,不能接收任何请求。为了解决这个问题,Redis又提供了一个叫做bgsave的命令。这个命令会单独创建一个子进程来负责将内存中的数据写入到硬盘中,这样的话主进程就可以继续处理请求了。但是这个过程中还会有一定的性能损耗,这段时间内Redis还是不能处理任何请求,没有办法做到秒级的快照为了解决这个问题,Redis又提供了另一种叫做AOF的持久化方式。
AOF的原理是在执行写命令的时候,不仅会将命令写入到内存中,还会将命令写入到一个追加的文件中,即AOF文件。它会以日志的形式来记录每一个写操作。当Redis重启时就会通过重新执行AOF文件中的命令,来在内存中重建整个数据库的内容。
三种部署模式
主从复制
主从复制是指将一台Redis服务器的数据复制到其他的Redis服务器,也叫主节点和从节点。一个主节点可以有多个从节点,而每个从节点只能有一个主节点,且数据的复制是单向的,只能从主节点到从节点。
一般来说,主节点负责写操作,从节点负责从操作,主节点会将自己的数据变化通过异步的方式发送给从节点,从节点接受到主节点的数据之后更新自己的数据,这样就达到了数据一致的目的。
哨兵模式
主从模式中,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址。显然,多数业务场景都不能接受这种故障处理方式。Redis从2.8开始正式提供了Redis Sentinel(哨兵)架构来解决这个问题。
哨兵模式就是由一个或多个Sentinel实例组成的Sentinel系统,它可以监视所有的Redis主节点和从节点,并在被监视的主节点进入下线状态时,自动将下线主服务器属下的某个从节点升级为新的主节点。但是呢,一个哨兵进程对Redis节点进行监控,就可能会出现问题(单点问题),因此,可以使用多个哨兵来进行监控Redis节点,并且各个哨兵之间还会进行监控。
Cluster集群模式
哨兵模式基于主从模式,实现读写分离,它还可以自动切换,系统可用性更高。但是它每个节点存储的数据是一样的,浪费内存,并且不好在线扩容。因此,Cluster集群应运而生,它在Redis3.0加入的,实现了Redis的分布式存储。对数据进行分片,也就是说每台Redis节点上存储不同的内容,来解决在线扩容的问题。并且,它也提供复制和故障转移的功能。
一个Redis集群由多个节点组成,各个节点之间通过Gossip协议进行通信
Redis Cluster集群通过Gossip协议进行通信,节点之前不断交换信息,交换的信息内容包括节点出现故障、新节点加入、主从节点变更信息、slot信息等等。常用的Gossip消息分为4种,分别是:ping、pong、meet、fail。