读完这篇文章,就基本搞定了Redis数据库


读完这篇文章,就基本搞定了Redis数据库

文章插图
 
 
简单来说 redis 就是一个数据库,不过与传统数据库不同的是 Redis 的数据是存在内存中的,所以存写速度非常快,因此 Redis 被广泛应用于缓存方向 。
 
另外,Redis 也经常用来做分布式锁 。Redis 提供了多种数据类型来支持不同的业务场景 。
 
除此之外,Redis 支持事务 、持久化、LUA 脚本、LRU 驱动事件、多种集群方案 。
 
本文将从以下几个方面全面解读 Redis:
  • 为什么要用 Redis / 为什么要用缓存
  • 为什么要用 Redis 而不用 map/guava 做缓存
  • Redis 和 Memcached 的区别
  • Redis 常见数据结构以及使用场景分析
  • Redis 设置过期时间
  • Redis 内存淘汰机制
  • Redis 持久化机制(怎么保证 Redis 挂掉之后再重启数据可以进行恢复)
  • Redis 事务
  • 缓存雪崩和缓存穿透问题解决方案
  • 如何解决 Redis 的并发竞争 Key 问题
  • 如何保证缓存与数据库双写时的数据一致性
 
为什么要用 Redis / 为什么要用缓存?
 
主要从“高性能”和“高并发”这两点来看待这个问题 。
 
高性能
 
读完这篇文章,就基本搞定了Redis数据库

文章插图
 
假如用户第一次访问数据库中的某些数据 。这个过程会比较慢,因为是从硬盘上读取的 。
 
将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了 。
 
操作缓存就是直接操作内存,所以速度相当快 。如果数据库中的对应数据改变了之后,同步改变缓存中相应的数据即可!
 
高并发
 
读完这篇文章,就基本搞定了Redis数据库

文章插图
 
直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库 。
 
为什么要用 Redis 而不用 map/guava 做缓存
 
缓存分为本地缓存和分布式缓存 。以 JAVA 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 JVM 的销毁而结束 。
 
并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性 。
 
使用 Redis 或 Memcached 之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性 。
 
缺点是需要保持 Redis 或 Memcached 服务的高可用,整个程序架构上较为复杂 。
 
Redis 和 Memcached 的区别
 
现在公司一般都是用 Redis 来实现缓存,而且 Redis 自身也越来越强大了!
 
对于 Redis 和 Memcached 我总结了下面四点:
  • Redis 支持更丰富的数据类型(支持更复杂的应用场景):Redis 不仅仅支持简单的 K/V 类型的数据,同时还提供 list、set、zset、hash 等数据结构的存储 。Memcache 支持简单的数据类型 String 。
  • Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而 Memecache 把数据全部存在内存之中 。
  • 集群模式:Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 Redis 目前是原生支持 Cluster 模式的 。
  • Memcached 是多线程,非阻塞 IO 复用的网络模型;Redis 使用单线程的多路 IO 复用模型 。
 
来自网络上的一张对比图,这里分享给大家:
读完这篇文章,就基本搞定了Redis数据库

文章插图
 
Redis 常见数据结构以及使用场景分析
 
String
 
常用命令:set、get、decr、incr、mget 等 。
 
String 数据结构是简单的 Key-Value 类型,Value 其实不仅可以是 String,也可以是数字 。常规 Key-Value 缓存应用;常规计数:微博数,粉丝数等 。
 
Hash
 
常用命令: hget、hset、hgetall 等 。
 
Hash 是一个 String 类型的 Field 和 Value 的映射表,Hash 特别适合用于存储对象 。
 
后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值 。比如我们可以 Hash 数据结构来存储用户信息,商品信息等等 。


推荐阅读