Redis 基础用法和三大问题

文章目录

  • Redis
      • 概述
      • String 实际应用场景
      • Session VS Cookie
      • Redis缓存产品特点
      • 缓存类型
      • 常用命令
      • 两种持久化备份数据方式 RDB 和 AOF
      • 应用场景
      • 缓存常见问题

Redis

概述

Redis 是一个完全开源的、由 C 语言编写、遵守 BSD 协议(BSD 开源协议是一个给予使用者很大自由的协议,可以自由的使用、修改源代码,也可以将修改后的代码作为开源或者专有软件再发布)、支持网络、可基于内存、分布式、可选持久性、高性能的键值对(key-value)存储数据库,并支持多种语言的 API 。

Redis 是远程的、基于内存的、是非关系型数据库。

由于值(value)可以是:字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Zset)等类型,所以 Redis 常被称为数据结构服务器。

  1. String:Redis 最基本的数据类型,一个 key 对应一个 value。二进制安全(可以包含任何数据,比如 jpg 图片或者序列化的对象。一个 Redis 字符串 value 最多可以是 512M。

  2. Hash:类似 Java 里的 Map,是一个键值对集合,是一个 String 类型的 field 和 value 的映射表,特别适合存储对象。

  3. List:简单的字符串列表,按照插入顺序排序,底层是个链表。可以通过 List 存储一些列表型的数据结构,类似粉丝列表、文章的评论列表之类的东西。

    也可以基于 List 实现分页查询,这个是很棒的一个功能,基于 Redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走。

  4. Set:String 类型的无序集合,通过 HashTable 实现。

  5. Zset:String 类型的有序集合,不允许重复的成员。

String 实际应用场景

String 类型是 Redis 中最常用的类型,内部的实现是通过 SDS (Simple Dynamic String,类似于 Java 中的 ArrayList)来存储的,可以通过分配冗余空间的方式来减少内存的频繁分配。

  • 缓存功能String 字符串是最常用的数据类型,不仅是 Redis,各个语言都是最基本类型。因此,利用 Redis 作为缓存,配合其它数据库作为存储层,利用 Redis 支持高并发的特点,可以大大加快系统的读写速度、降低后端数据库的压力。
  • 计数器:许多系统都会使用 Redis 作为系统的实时计数器,可以快速实现计数和查询的功能。而且最终的数据结果,可以按照特定的时间持久化到数据库或者其它存储介质当中。
  • 共享用户 Session:用户重新刷新一次界面,可能需要访问一下数据进行重新登录,或者访问页面缓存 Cookie,但是现在我们可以利用 Redis 将用户的 Session 集中管理,在这种模式只需要保证 Redis 的高可用,每次用户 Session 的更新和获取都可以快速完成,大大提高效率。

Session VS Cookie

  • Session 存储在服务器上,对于客户端是透明的;Cookie 存储在客户端阅读器中,对于客户端是可见的。
  • Session 的作用是实现网页之间数据传递,是一种存储在服务器端的对象集合。具有极高的简便性、可扩展性、可用性,也可以通过加密的 SSL 技术来提高其信息安全性。它是一种服务器的机制,服务器使用一种类似于散列表的结构来保存信息。
  • Cookie 是在 HTTP 协议下,服务器或脚本可以维护客户端工作站上信息的一种方式,可以看作浏览器缓存。是由 Web 服务器保存在用户浏览器(客户端)上的小文本文件(内容通过加密),它可以包含有关用户的信息,并且,无论何时用户连接到服务器,Web 站点都可以访问 Cookie 信息。
  • 两者最大的区别就是在于生存周期,浏览器页面关闭 session 就消失了,而 cookie 是预设生存周期并且可以永久保存于本地文件(网页记住用户信息进行自动登录)。

Redis缓存产品特点

  1. 支持数据持久化,可将内存中的数据保存在磁盘里,重启时再次加载使用;
  2. 不仅支持简单的 key-value 类型的数据,还提供 hash、list、set、zset 等数据结构的存储;
  3. 支持数据备份,即 master-slave 模式(主从服务器:主服务器宕机后,从服务器立马代替,做到无缝衔接)。
  4. 原子性,Redis 的所有操作都是原子性的,即命令要么成功执行,要么失败完全不执行。单个操作原子性,多个操作支持事务(原子性)。

缓存类型

缓存是高并发场景下提高热点数据访问性能的一个有效手段。缓存类型分为:本地缓存、分布式缓存、多级缓存。

  • 本地缓存:在进程的内存中进行缓存,比如我们的 JVM 堆中。本地缓存是内存访问,没有远程交互开销,性能最好。缺点是受限于单机容量,一般缓存较小且无法扩展。
  • 分布式缓存:可以很好地解决本地缓存的问题,分布式缓存一般都具有良好的水平扩展能力,对叫大数据量的场景也能应付自如。缺点是需要进行远程请求,性能不如本地缓存。
  • 多级缓存:为了平衡以上的情况,实际业务一般采用多级缓存。本地缓存只访问频率最高的部分热点数据,其他的热点数据放在分布式缓存中。在目前的一线大厂中,这也是最常用的缓存方案,单一的缓存方案往往难以撑住很多高并发的场景。

常用命令

  1. Redis 默认有16个数据库
  2. select 数据库名:进入对应的数据库
  3. keys *:列出所有 key 值
  4. dbsize:显示数据库数
  5. flushdb:清除该数据库的 key
  6. flushall:清除所有
  7. exist key:判断 key 是否存在

两种持久化备份数据方式 RDB 和 AOF

  1. RDB:Redis DataBase,指定时间间隔内,将内存中的数据集快照(snapshot)写入磁盘。恢复时是将快照文件直接读入内存中来达到数据恢复的。

    Redis 会单独创建一个子进程来进行持久化(我们可以在做项目过程中自己模拟:创建一个线程来持久化),会先将数据写进一个临时文件中,等到持久化过程结束了,在用这个临时文件替换上次持久化好的文件。在这个过程中,只有子进程来负责 IO 操作,主进程任然处理客户端的请求,保证了极高的性能

    在默认情况下,Redis 将数据库快照保存在 dump.rdb 的二进制文件中,通过触发快照的形式,做到将指定时间间隔内的数据持久化到 dump.rdb。例如:可以2分钟内持久化一次,将对数据库的写操作备份到磁盘上的 dump.rdb。

  2. AOF:Append Only File,以日志的形式记录 Redis 每一个写操作,将 Redis 执行过的所有指令记录下来(读操作不记录),只允许追加文件而不允许改写。Redis 启动之后会读取 appendonly.aof 文件来实现重新恢复数据。默认不开启,需要将 redis.conf 中的 appendonly no 改为 yes 。

  3. 两者如何选择:如果想达到较高的数据安全性,应该同时使用两种持久化方式。有很多用户只是用 AOF 方式,但是并不推荐,因为定时生成 RDB 快照非常便于进行数据库备份,而且 RDB 恢复数据集的速度也更快。所以,如果可以承受数分钟内的数据丢失,可以只使用 RDB 持久化。

应用场景

数据缓存、队列原子性、数据存储。

缓存常见问题

  • 缓存穿透

    在大多数互联网应用中,缓存的使用方式是:业务系统 -> 缓存 -> 数据库。

    1. 业务系统发起某一个查询请求,首先判断缓存中是否有该数据;
    2. 如果缓存中存在,则直接返回给服务端;
    3. 若果不存在,就去查询数据库,然后返回。

    缓存穿透就是业务系统访问了根本不存在的数据,数据库返回空。

    危害:如果海量请求查询不存在的数据,那么这些请求就都会落到数据库,数据库压力剧增,可能导致系统崩溃。

    解决:将数据库查询结果为空的 key 也存到缓存中,并设置较短的生命周期,节省内存空间。

  • 缓存雪崩

    缓存实际上是为了保护数据库,帮数据库抵挡大量的查询请求,从而避免脆弱的数据库受到伤害。当缓存因某种原因失效,原本被缓存抵挡的海量请求就会涌向数据库,此时数据库若抵挡不了崩溃,这就是缓存雪崩。

    解决:开启备用缓存。

  • 缓存击穿:(热点数据集中失效)

    我们一般会给缓存设定一个失效时间,超时后该数据库会被缓存直接删除,一定程度上保证数据的实时性。

    但是,对于一些请求量极高的热点数据,一旦过了有效时间,那么将会有大量的请求落在数据库上,从而可能导致数据库崩溃。

    解决:互斥锁。只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完成,重新从缓存获取数据即可。

你可能感兴趣的:(redis,缓存,java)