持久化

Redis 支持持久化, 其持久化数据有两种方式. 两种可以同时使用. 如果同时使用, Reids 在重启时将使用 AOF 方式来还原数据.

RDB

按照一定策略定时同步内存的数据到磁盘.文件名 dump.rdb

  • snapshot: 快照复制. Redis在指定情况下触发快照: (1) 按配置的规则;(2) save 或 bgsave 命令执行;(3) flushall 命令; (4)执行复制

    1. 配置的规则: save seconds exchange 当在 seconds 指定的时间内, key 的数量更改大于 exchange 时发生快照.

    2. save 或 bgsave 命令: 执行快照同步操作, 注意save这个操作会暂时阻塞客户端请求. bgsave则不会阻塞

    3. flushall: 清除内存所有数据, 只要规则不为空, redis就会执行快照

    4. 执行复制:

  • 快照原理

    fork 复制一份当前进程的副本, 这个进程是子进程, 负责同步持久化到磁盘. 而父进程负责处理客户端请求.

  • 快照的优缺点:

    1. 缺点: 可能会丢失数据, 在下一次快照前宕机
    2. 优点: 最大化Redis的性能, 父子进程职责分离

AOF

保存命令到磁盘, 也就是持久化日志.

  • 配置: appendonly yes 启动aof. 默认的文件名是 appendonly.aof.

  • 配置 auto-aof-rewrite-percentage 100 当 aof 文件与上一次文件的大小相比, 超过配置的百分比就进行重写

  • 配置 auto-aof-rewrite-min-size 64m 限制允许重写最小 aof 文件大小, 即小于64m时不重写

  • aof 重写原理: aof 重写是安全的. 相当于同时将命令追加到现有的aof文件, 同时写入新的 aof 临时文件, 临时文件最终将覆盖原 aof 文件.

  • 同步磁盘数据: aof机制会将命令记录到aof文件, 但实际是同步到操作系统的缓存区, 最终由操作系统同步到磁盘. 可以通过下面配置修改策略

    appendsync always 每次执行写入就同步, 安全但影响性能

    appendsync everysec 每一秒执行

    appendsync no 不执行同步, 由操作系统去执行, 效率高但不安全

  • aof 文件损坏后的修复, 使用redis-check-aof-fix

集群

master/slave 复制

主从方式, 从是只读的, slave也可以有自己的slave.

  • slave节点上配置 slaveof masterip masterport

  • 配置 slave-serve-stale-data no 可以用来保证数据同步后再做其他操作

  • 命令info replication可以查看信息.

  • 实现原理:

    1. slave 连接到 master 后, 会向 master 发送 SYNC 命令.
    2. master 收到命令后, 会做两件事(1) 执行bgsave;(2)master 将收到的修改命令存入缓冲区, 再将命令传输给slave
  • 复制方式:

    1. 基于rdb文件复制
    2. 无硬盘复制 配置rpli-diskless-sync yes
    3. 增量复制 PSYNC master run id. offset
  • 命令replconf listening-port 6379可以用来查看复制过程

  • 缺点: 无法做master选举

sentinale 哨兵模式

  1. 监控
  2. master选举
  • 配置文件为sentinel.conf

  • 配置节点: sentinel monitor mymaster 192,168,11,111 6379 2 最后的2为投票数

  • 是高可用方案, 但不是高性能方案

集群

  • 原理

    Reids有slot槽的概念: redis中有16384个. 根据key的 CRC16 算法, 取得的结果与槽数取模.落入的槽的索引是固定的. 然后根据节点数将槽的范围确定到每个节点上.

    当节点新增和删除时, 节点的槽范围发生变化, 数据迁移需要人工干预.

  • 三方方案

    1. redis shardding : jedis支持
    2. codis : 代理, 分片和数据迁移自动化
    3. twemproxy :

缓存穿透问题

  • 数据库中不存在的对象查询后也缓存.
if(objJson!=null){
redisService.expire("key",timeout:3*60);
} else {
redisService.expire("key",timeout:5); //5秒内不查询数据库
}
  • synchronized 方法, 不理想, 排队影响性能.
  • 同步块, 需要双重判定, 否则阻塞的线程均会查询数据库, 代码如下
String value = redisService.get("key");
if(value==null){
synchronized(lock){
value = redisService.get("key"); //多线程再次查询,防止数据库多次查询
if(value==null){
value = dao.get();
redisService.set("key",value);
if(objJson!=null){
redisService.expire("key",timeout:3*60);
} else {
redisService.expire("key",timeout:5); //5秒内不查询数据库
}
}
}
}
  • 使用ReentrantLocktryLock(),else中线程等待一段时间, 这样不阻塞进程

  • 使用分布式锁

if(redisService.setNx("key")==true){
//查询数据库
}
  • 不设超时时间或设置一个较长的超时时间, 然后判断当前时间是否超过缓存时间, 结合分布式锁, 超过则刷新缓存. 此解决方法可能会发生少量数据不一致的情况.

采用何种策略需要结合实际需求, 是保证可用, 还是保证一致性? 对于一致性要求不高的场景, 可能最后一种方案可以彻底解决击穿问题. 对于一致性要求较高的场景, 使用同步/锁的方式会更好.

分布式系列十二: Redis高级主题的更多相关文章

  1. Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】

    2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...

  2. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  3. Redis高级主题

    Redis高级主题   持久化 Redis 支持持久化, 其持久化数据有两种方式. 两种可以同时使用. 如果同时使用, Reids 在重启时将使用 AOF 方式来还原数据. RDB 按照一定策略定时同 ...

  4. SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据

    原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...

  5. struts2官方 中文教程 系列十二:控制标签

    介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...

  6. 爬虫系列(十二) selenium的基本使用

    一.selenium 简介 随着网络技术的发展,目前大部分网站都采用动态加载技术,常见的有 JavaScript 动态渲染和 Ajax 动态加载 对于爬取这些网站,一般有两种思路: 分析 Ajax 请 ...

  7. Alamofire源码解读系列(十二)之时间轴(Timeline)

    本篇带来Alamofire中关于Timeline的一些思路 前言 Timeline翻译后的意思是时间轴,可以表示一个事件从开始到结束的时间节点.时间轴的概念能够应用在很多地方,比如说微博的主页就是一个 ...

  8. 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  9. SpringBoot系列(十二)过滤器配置详解

    SpringBoot(十二)过滤器详解 往期精彩推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件 ...

随机推荐

  1. On the structure of submodule of finitely generated module over PID

    I was absorbed into this problem for three whole days......

  2. protobuf使用详解

    https://blog.csdn.net/skh2015java/article/details/78404235 原文地址:http://blog.csdn.net/lyjshen/article ...

  3. CentOS配置svn

    参考: https://www.cnblogs.com/taohaijun/p/7172939.html 1.检查已安装版本  rpm -qa subversion 卸载旧版本SVN yum remo ...

  4. path node

    process.cwd() 当前Node.js进程执行时的工作目录 __dirname 当前模块的目录名 const path = require('path'); console.log(__dir ...

  5. 【pytorch】pytorch-LSTM

    pytorch-LSTM() torch.nn包下实现了LSTM函数,实现LSTM层.多个LSTMcell组合起来是LSTM. LSTM自动实现了前向传播,不需要自己对序列进行迭代. LSTM的用到的 ...

  6. <TCP/IP原理> (二) OSI模型和TCP/IP协议族

    1.OSI参考模型 1)作用 2)各层的名称和功能 2.对分层网络协议体系的理解 1)不同节点:层次组成不同,作用不同 2)横向理解:虚通信.对等实体.协议.PDU 3)纵向理解:封装与解封.服务.接 ...

  7. practice01

    1. 组合数公式: C(n, k) =C(n-1, k) +C(n-1, k-1) 要求利用该公式写递归函数求组合数. #include <stdio.h> int C(int a,int ...

  8. nexus5 root

    LG nexus5 安装新的lineage 14.1系统卡刷 supersuV2.82失败,开机卡动画界面. 改回刷入2016年11月下的cm 13 的包,三清后卡刷supersuV2.82,成功.

  9. Neovim中NERDTree等多处cursorline不高亮

    标题表达的不是很清楚,看下图把 解决方法 添加下面内容到init.vim " 针对NERDTree " https://github.com/scrooloose/nerdtree ...

  10. Promise的源码实现(完美符合Promise/A+规范)

    Promise是前端面试中的高频问题,我作为面试官的时候,问Promise的概率超过90%,据我所知,大多数公司,都会问一些关于Promise的问题.如果你能根据PromiseA+的规范,写出符合规范 ...