Redis概述
简单来说,redis是一个数据库,但与传统数据库不同的是,redis数据存储在内存中,使得保存和写入都非常快。
这个Redis广泛应用于缓存方向。此外,Redis 经常用于分布式锁定。 redis提供不同的数据类型来支持不同的行业
业务场景。此外,redis 支持事务、持久性、LUA 脚本、LRU 驱动的事件和各种集群解决方案。
为什么要使用Redis?
看待这个问题主要有两个方面:高性能和高并发。
让我们来看看它的高性能吧!
假设用户第一次访问数据库中的数据。此过程需要时间,因为它是从硬盘读取的。将用户访问的数据存储在数据缓存中,以便用户下次访问时可以直接从缓存中检索数据。缓存操作相当快,因为它们直接在内存上操作。
如果数据库中对应的数据发生变化,只需同步更改缓存中对应的数据即可。
下一步是高并发。
因为直接操作缓存可以承受比直接访问数据库大得多的请求,所以可以将数据库中的一些数据转移到缓存中,这样用户的一些请求就可以绕过缓存,直接进入缓存,可以考虑允许。它将发送给您。数据库。
为什么使用Redis而不是Map/Guava进行缓存?
缓存分为本地缓存和分布式缓存。以Java为例,本地缓存是使用内置的map或者guava来实现的。主要特点是生命周期随着jvm的销毁而结束。如果有多个实例,则每个实例都会被销毁。你需要为每个实例存储一个缓存,但是缓存并不一致。
使用redis或memcached称为分布式缓存。对于多个实例,每个实例共享数据的缓存,并且缓存是一致的。缺点是需要保持redis或者memcached服务的高可用,整体程序架构比较复杂。
4.redis和memcached的区别
我把redis和memcached总结为以下四点。如今,企业普遍使用Redis来实现缓存,并且Redis本身也变得越来越强大。
1、Redis支持更丰富的数据类型(支持更复杂的应用场景):Redis不仅支持简单的k/v类型数据,还支持list、set、zset、hash等数据结构的存储。 memcache 支持一种简单的数据类型:String。
2、Redis支持数据持久化。这允许数据保存在磁盘上的内存中并重新加载以供重新启动时使用。
Memecache 将所有数据存储在内存中。
3.集群模式:Memcached没有原生集群模式,必须依赖客户端将数据写入集群内的分片。然而,它目前依赖于Redis。
原生支持集群模式。
4、Memcached是多线程、非阻塞IO复用网络模型,而Redis则采用单线程、多通道IO复用模型。
redis常见数据结构及使用场景分析
1. 字符串
常用命令: set、get、decr、incr、mget 等
String 数据结构是一种简单的键值类型。事实上,该值不仅可以是字符串,还可以是数字。
传统的key-value缓存应用,传统的统计:微博数、粉丝数等。
2.哈希值
常用命令:hget、hset、hgetall等。
哈希是一个字段和字符串类型值的映射表,适合在后续操作时直接只改变这个对象的某些字段的值。 例如,可以使用哈希数据结构来存储用户信息、产品信息等。例如,下面我使用哈希类型来存储我的一些信息。
key=JavaUser293847value={“id”: 1,“姓名”:“SnailClimb”,“年龄”:22,“位置”:“湖北省武汉市”}3.列表
常用命令: lpush、rpush、lpop、rpop、lrange 等List是一种链表,它的应用场景很多,也是Redis中最重要的数据结构之一,比如微博关注列表、粉丝列表等。消息列表和所有其他功能都可以使用Redis 列表结构来实现。
Redis列表被实现为双向链表,可以支持向后搜索和遍历,使它们使用起来更方便,但代价是额外的内存开销。此外,您可以使用lrange 命令读取从特定元素开始的元素数。这是一个很棒的功能,可以让你基于redis实现简单的高性能分页,并进行持续拉取。 -down 对于像微博这样的分页(逐页向下移动)性能很高。
4.设置
常用命令:sadd、spop、smembers、sunion等。
set提供的外部功能与list类似,但特殊的是set可以自动去除重复项。
如果需要存储数据列表并且不想重复数据,set是一个不错的选择。集合提供了一个重要的接口,用于确定某个成员是否包含在集合集合中,这是列表无法提供的。基于集合可以方便地实现交、并、差运算。
示例:在微博应用中,您可以将用户的所有关注者保存到集合中,将所有粉丝保存到集合中。 Redis可以让你非常方便的实现共同关注、共同粉丝、共同配置等功能。这个过程也是一个寻找交集的过程。具体命令为:
sinterstore key1 key2key3 将公共部分存储在key1 中。 5.有序集
常用命令:zadd、zrange、zrem、zcard等。
相比于集合,有序集合增加了权重参数的分数,因此可以根据分数对集合中的元素进行排序。
举例:在直播系统中,实时排名信息包括直播间在线用户列表、各种礼物排名、集中消息(可以理解为按照消息维度的消息排名)等。使用Redis的SortedSet结构进行存储。
6.redis设置过期日期
Redis 具有过期功能,允许您为Redis 数据库中存储的值设置过期时间。这作为缓存数据库非常有用。例如,典型项目中的令牌和一些登录信息,尤其是短信验证码,都有一个过期日期,而传统的数据库处理方法通常需要您自己确定过期日期,这对项目性能可能至关重要。怀疑会有影响。
设置密钥时,您可以指定到期日期。通过过期,您可以指定密钥可以持续多长时间。
假设我设置了一批只能持续1小时的key,那么Redis如何在下一小时后删除这批key呢?从名字上你大概就能猜到这两种删除方法的含义了。
定期删除:默认情况下,Redis 每100 毫秒随机选择一个有过期日期的key,检查它是否过期,如果过期则将其删除。
请注意,这是随机选择的。为什么是随机的?如果你想一想,如果Redis 存储了数十万个键,并且每100 毫秒扫描一次它们的过期时间,这会给CPU 带来很大的压力。
延迟删除:定期删除可能会导致许多过期密钥在过期时未被删除。因此,出现延迟删除。如果过期的密钥没有通过定期删除的方式删除并保留在内存中,Redis 将删除它,除非系统检查该密钥。这就是所谓的懒删除,已经够懒了,但是仅仅设置一个过期日期还是有问题的。我们想一想。如果定期删除漏掉了很多过期的key,而因为没有及时检查而无法进行惰性删除怎么办?我怎么解决这个问题?
Redis内存删除机制。
7.redis内存删除机制(MySQL有2000万条数据,
如果你有20万条数据,如何保证Redis中的所有数据都是热数据?
Redis配置文件redis.conf中有相关注释,这里就不贴出来了。亲自检查或通过以下网站检查:
http://download.redis.io/redis-stable/redis.conf
Redis提供了六种数据删除策略。
5. volatile-lru:从过期数据集(server.db[i].expires)中选择最近最少使用的数据进行删除。
6. volatile-ttl:从具有过期日期(server.db[i].expires)的数据集中选择并删除即将过期的数据。
7. volatile-random:设置一个过期时间,可以任意选择数据从数据集中删除(server.db[i].expires)。
8. allkeys-lru:如果内存不足以容纳新写入的数据,则删除键空间中最近最少使用的键(也是最常用的)。
9. allkeys-random:从数据集中任意选择要删除的数据(server.db[i].dict)
10. 不驱逐:防止数据驱逐。这意味着如果没有足够的内存来容纳新写入的数据,新的写入操作将报告错误。没有人应该使用这个!
8.redis持久化机制(如何保证redis挂掉重启后数据可以恢复)
数据通常需要持久化。即内存中的数据必须写入硬盘。这样做的原因大多是为了以后重用数据(例如重启机器、机器故障后恢复数据),或者备份。远程存储数据以防止系统故障。
Redis 与Memcached 的一个重要区别在于Redis 支持持久化,并且支持两种不同的持久化操作。 Redis 的一种持久化方法称为快照(RDB),另一种是仅追加(append-only)。
fifile、AOF)这两种方法各有优点,我们将详细说明这两种持久化方法是什么、如何使用它们以及如何选择适合您的持久化方法。
快照和持久化(RDB)
Redis 可以创建快照来获取特定时间点存储在内存中的数据的副本。 Redis 拍摄快照后,可以将该快照复制到其他服务器上,以创建包含相同数据的服务器副本(Redis 的主/从结构;主要用于提高Redis 性能)。使用时需要重新启动服务器。
快照持久化是Redis使用的默认持久化方式,在redis.conf配置文件中包含以下默认配置。
save 9001 命令创建快照。 #900 几秒(15 分钟)后,如果至少有一个键发生变化,Redis 会自动触发BGSAVE 命令save 300 10 创建快照。 #300秒(5分钟)后,如果至少有10个key发生变化,Redis会自动触发BGSAVE命令save 60 10000创建快照。 #60秒(1分钟)且至少10000个key发生变化后,Redis自动触发BGSAVE命令AOF(append-only fifile)持久化。
相比快照持久化,AOF持久化具有更好的实时性,成为主流的持久化方案。默认情况下不启用Redis
可以使用appendonly参数启用AOF(仅追加文件)持久性。
appendonly 是启用AOF 持久化后,每次运行修改Redis 中数据的命令时,Redis 都会将该命令写入硬盘上的AOF 文件中。 AOF 文件保护
存储位置与RDB文件位置相同,均由dir参数设置。默认文件名是appendonly.aof。
Redis配置文件中存在三种不同的AOF持久化方式:
appendfsync #每次发生数据变化时都会写入AOF文件,这会显着减慢Redis的速度。 appendfsync Everysec #1 每秒同步一次,并显式地将多个写入命令同步到硬盘。 appendfsync no # 要通过让操作系统决定何时同步数据和写入性能,请使用appendfsync Everysec选项,该选项允许Redis每秒同步一次AOF文件,对Redis性能影响很小,可以考虑。此外,如果系统崩溃,用户最多只会丢失一秒内生成的数据。当硬盘忙于执行写入操作时,Redis 会优雅地放慢速度以适应硬盘的最大写入速度。
优化Redis 4.0持久化机制
Redis 4.0开始支持混合RDB和AOF持久化(默认关闭,但可以通过配置项打开)。
开启混合持久化后,重写AOF 时,RDB 内容会直接写入到AOF 文件的开头。这样做的好处是结合了RDB和AOF的优点,可以快速加载,同时避免过多的数据丢失。当然,AOF的RDB部分是压缩格式,而不是AOF格式,这样阅读起来比较困难。
补充内容:AOF重写
重写AOF会生成一个新的AOF文件。这个新的AOF 文件与原始AOF 文件具有相同的数据库状态,但大小更小。
AOF 重写这个名字是有歧义的。该功能是通过读取数据库中的键值对来实现的。该程序不需要读取、分析和写入现有的AOF 文件。
当您运行BGREWRITEAOF 命令时,Redis 服务器会维护一个AOF 重写缓冲区。该缓冲区记录子进程创建新AOF 文件时服务器执行的所有写入命令。当子进程完成创建新的AOF 文件时,服务器将重写缓冲区中的所有内容追加到新AOF 文件的末尾,确保新旧AOF 文件中的数据库状态匹配。最后,服务器用新的AOF文件替换旧的AOF文件,完成AOF文件重写操作。
9.redis事务
Redis 通过MULTI、EXEC 和WATCH 等命令实现事务功能。事务提供了一种打包多个命令请求并按顺序一次执行多个命令的机制。当事务正在运行时,服务器不会中止事务并执行事务内的所有命令。在处理来自其他客户端的命令请求之前执行。传统关系数据库经常使用ACID 属性来测试事务功能的可靠性和安全性。在Redis中,事务总是原子的、一致的、隔离的,如果Redis运行在某种持久模式下,事务也是持久的。
10.Redis常见异常及解决方案
使用缓存时常遇到的一些问题可以总结为四点:
10.1 缓存入侵
分布式锁可以防止不同进程重复相同的工作,减少资源浪费。 同时,分布式锁定可以避免损害数据完整性。
多个流程处理同一订单等不准确情况可能会覆盖订单状态中的错误。应用场景如下。
11.1.1 重复计划任务
跟随
着业务的发展,业务系统势必发展为集群分布式模式。如果我们需要一个定时任务来进行订单状 态的统计。比如每 15 分钟统计一下所有未支付的订单数量。那么我们启动定时任务的时候,肯 定不能同一时刻多个业务后台服务都去执行定时任务, 这样就会带来重复计算以及业务逻辑混乱 的问题。 这时候,就需要使用分布式锁,进行资源的锁定。那么在执行定时任务的函数中,首先进行分布式 锁的获取,如果可以获取的到,那么这台机器就执行正常的业务数据统计逻辑计算。如果获取不到 则证明目前已有其他的服务进程执行这个定时任务,就不用自己操作执行了,只需要返回就行了。 如下图所示: