什么是redis?
Redis(Remote Dictionary Server,远程字典服务)是一个开源的、基于键值对的内存数据结构存储系统,可以用作数据库、缓存和消息中间件。Redis支持多种数据结构,如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等,并且提供了丰富的命令来操作这些数据结构。
什么是NOSQL?
NoSQL(Not Only SQL)数据库是一种非关系型的数据库,它与传统的SQL数据库(如MySQL、Oracle等关系型数据库)不同。NoSQL数据库的设计目的是为了应对大规模数据存储的需求,特别是在处理海量数据和高并发访问场景下,提供更好的性能、灵活性和可扩展性。NoSQL数据库通常用于Web应用、大数据处理、实时分析等领域。
NoSQL数据库的主要特点包括:
1. 非关系型结构:NoSQL数据库不使用表、行或列的概念,而是采用键值对、文档、列族或图形等多种数据模型来组织数据。
2. 水平扩展:NoSQL数据库设计时就考虑到了分布式存储,可以很容易地通过增加更多的服务器来实现水平扩展,以支持更大的数据量和更高的并发请求。
3. 高可用性和容错性:大多数NoSQL数据库都内置了复制机制,可以在多个节点之间复制数据,从而提高系统的可用性和容错性。
4. 灵活的数据模式:NoSQL数据库通常允许动态更改数据模式,这意味着应用程序可以在运行时添加新的字段而不需要停机维护。
5. 弱一致性:为了提高性能和可扩展性,NoSQL数据库可能会牺牲一定的数据一致性,采取最终一致性的策略。
根据不同的数据模型,NoSQL数据库可以分为以下几类:
键值存储:如Amazon DynamoDB、Riak等,适用于需要快速查找特定记录的应用。
文档存储:如MongoDB、CouchDB等,适合存储复杂的数据结构,如JSON格式的文档。
列族存储:如Apache Cassandra、HBase等,适合处理大规模的数据集和高写入负载。
图形数据库:如Neo4j、JanusGraph等,适用于需要表示和查询复杂关系的数据集。
NOSQL优势和缺点
优势
1. 水平扩展性:
NoSQL数据库设计之初就考虑到了分布式存储,可以通过增加更多的服务器节点轻松实现水平扩展,以支持更大的数据量和更高的并发请求。
- 这种扩展性特别适合云计算环境和大型互联网应用。2. 高性能:
由于NoSQL数据库通常将数据存储在内存中,或者优化了磁盘I/O,因此它们能够提供非常高的读写性能。
特别是在处理大量简单查询时,NoSQL数据库的性能优势尤为明显。3. 灵活的数据模型:
NoSQL数据库支持多种数据模型,如键值对、文档、列族和图形等,可以根据应用需求选择最合适的数据模型。
数据模式通常是动态的,可以随时添加新的字段或修改现有字段,无需停机维护。4. 高可用性和容错性:
大多数NoSQL数据库都内置了复制机制,可以在多个节点之间复制数据,从而提高系统的可用性和容错性。
即使某个节点发生故障,系统也可以继续正常运行。5. 成本效益:
NoSQL数据库通常使用廉价的商用硬件,而不是昂贵的高端服务器,因此在大规模部署时更具成本效益。缺点
1. 弱一致性:
为了提高性能和可扩展性,NoSQL数据库通常采用最终一致性模型,而不是强一致性模型。
这意味着在某些情况下,数据可能不会立即在所有节点上保持一致,可能会导致短暂的数据不一致问题。2. 查询能力有限:
相比于关系型数据库,NoSQL数据库的查询能力通常较为有限,尤其是在处理复杂的多表联接和聚合查询时。
一些NoSQL数据库可能不支持SQL语言,学习和使用成本较高。3. 缺乏标准化:
NoSQL数据库种类繁多,每种数据库都有自己的数据模型和API,缺乏统一的标准。
这增加了开发和维护的复杂性,特别是当需要在不同类型的NoSQL数据库之间迁移数据时。4. 事务支持有限:
虽然一些NoSQL数据库支持基本的事务功能,但大多数NoSQL数据库在事务支持方面不如关系型数据库强大。
特别是跨多个数据项的复杂事务处理能力较弱。5. 管理复杂性:
分布式架构虽然带来了扩展性和性能优势,但也增加了管理和维护的复杂性。
需要专业的运维团队来确保系统的稳定性和性能。
Redis的过期键的删除策略
Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理。
惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地.节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。)
Redis中同时使用了惰性过期和定期过期两种过期策略。
简述Redis事务实现
1、事务开始
MULT/命令的执行,标识着一个事务的开始。MULT/命令会将客户端状态的flags 属性中打开REDIS MULTI 标识来完成的。
2、命令入队
当一个客户端切换到事务状态之后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客户端发送的命令为MULT、EXEC、WATCH、DISCARD中的一个,立即执行这个命令,否则将命令放入一个事务队列里面,然后向客户端返回 QUEUED 回复
如果客户端发送的命令为 EXEC、DISCARD、WATCH、MULTI四个命令的其中一个,那么服务器立即执行这个命令。
如果客户端发送的是四个命令以外的其他命令,那么服务器并不立即执行这个命令。首先检查此命令的格式是否正确,如果不正确,服务器会在客户端状态(redisClient)的 flags 属性关闭 REDIS_MULTI 标识,并且返回错误信息给客户端。如果正确,将这个命令放入一个事务队列里面,然后向客户端返回 QUEUED 回复
事务队列是按照FIFO的方式保存入队的命令
3、事务执行
客户端发送 EXEC 命令,服务器执行 EXEC 命令逻辑。
如果客户端状态的 flags 属性不包含 REDIS_MULTI 标识,或者包含 REDIS_DIRTY_CAS 或者REDIS DIRTY_EXEC 标识,那么就直接取消事务的执行,
否则客户端处于事务状态(flagS 有 REDIS_MULTI标识),服务器会遍历客户端的事务队列,然后执行事务队列中的所有命令,最后将返回结果全部返回给客户端;
redis 不支持事务回滚机制,但是它会检查每一个事务中的命令是否错误。
Redis 事务不支持检查那些程序员自己逻辑错误。例如对 String 类型的数据库键执行对 HashMap 类型的操作!WATCH 命令是一个乐观锁,可以为 Redis 事务提供 check-and-set(CAS)行为。可以监控-个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令。
MULTI命令用于开启一个事务,它总是返回OK。MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当EXEC命令被调用时,所有队列中的命令才会被执行,
EXEC:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。
当操作被打断时,返回空值 nil 。
通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务,并且客户端会从事务状态中退出。
UNWATCH命令可以取消watch对所有key的监控
Redis有哪些数据结构?分别有哪些典型的应用场景?
Redis的数据结构有:
1.字符串:可以用来做最简单的数据,可以缓存某个简单的字符串,也可以缓存某个ison格式的字符串,Redis分布式锁的实现就利用了这种数据结构,还包括可以实现计数器、Session共享、分布式1D
2.哈希表:可以用来存储一些key-value对,更适合用来存储对象
3.列表:Redis的列表通过命令的组合,既可以当做栈,也可以当做队列来使用,可以用来缓存类似微信公众号、微博等消息流数据
4.集合:和列表类似,也可以存储多个元素,但是不能重复,集合可以进行交集、并集、差集操作,从而可以实现类似,我和某人共同关注的人、朋友圈点赞等功能5.有序集合:集合是无序的,有序集合可以设置顺序,可以用来实现排行榜功能
Redis和Mysql如何保证数据一致
1.先更新Mysql,再更新Redis,如果更新Redis失败,可能仍然不一致2.先删除Redis缓存数据,再更新Mysql,再次查询的时候在将数据添加到缓存中,这种方案能解决1方案的问题,但是在高并发下性能较低,而且仍然会出现数据不一致的问题,比如线程1删除了Redis缓存数据,正在更新Mysql,此时另外一个查询再查询,那么就会把Mysql中老数据又查到Redis中
3.延时双删,步骤是:先删除Redis缓存数据,再更新Mysq,延迟几百毫秒再删除Redis缓存数据这样就算在更新Mysql时,有其他线程读了Mysql,把老数据读到了Redis中,那么也会被删除掉从而把数据保持一致
简述Redis事务实现
事务开始:MULTI命令的执行,标识着一个事务的开始。MULTI命令会将客户端状态的 flags属性
中打开REDIS MULTI标识来完成的。命令入队:当一个客户端切换到事务状态之后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客 户端发送的命令为MULTI、EXEC、WATCH、DISCARD中的一个,立即执行这个命令,否则将命令放入一 个事务队列里面,然后向客户端返回QUEUED回复,如果客户端发送的命令为 EXEC、DISCARD、WATCH、MULTI四个命令的其中一个,那么服务器立即执行这个命令。如果客户端发送的是四个命令以外的其他命令,那么服务器并不立即执行这个命令。首先检查此命令的格式是否正确,如果不正确,服务器会在客户端状态(redisClient)的 flags 属性关闭REDIS_MULTI标识,并且返回错误信息给客户端。如果正确,将这个命令放入一个事务队列里面,然后向客户端返回 QUEUED 回复事务队列是按照FIFO的方式保存入队的命令
事务执行:客户端发送 EXEC 命令,服务器执行 EXEC 命令逻辑。如果客户端状态的 flags 属性不包含 REDIS_MULTI标识,或者包含 REDIS_DIRTY_CAS 或者REDIS_DIRTY_EXEC 标识,那么就直接取消事务的执行。否则客户端处于事务状态(flags有 REDIS MULTI标识),服务器会遍历客户端的事务队列,然后执行事务队列中的所有命令,最后将返回结果全部返回给客户端;Redis不支持事务回滚机制,但是它会检查每一个事务中的命令是否错误。Redis事务不支持检查那些程序员自己逻辑错误。例如对 String 类型的数据库键执行对 HashMap 类型的操作