之前的讲解,主要是在讲解redis如何支撑海量数据、高并发读写、高可用服务的架构

从这一讲开始,正式开始做业务系统的开发

商品详情页,缓存架构,90%是大量的业务(没有什么级数含量),10%最有级数含量的就是架构

1、上亿流量的商品详情页的多级缓存架构

采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat 堆缓存的多级缓存架构

               nginx 本地缓存

                                        redis分布式缓存

                                     tomcat web应用 堆缓存

实时性要求非常高的数据:库存(希望当库存变化的时候,尽可能更快将库存显示到页面上去,而不是等了很长时间,库存才反应到页面上去)

实时性要求不高的数据:商品的基本信息(名称、颜色、版本、规格参数、等等)

对于实时性较高的数据来说,采用MYSQL和redis缓存双写的方案,这样缓存的时效性最高

nginx+lua脚本

lua脚本作为代码,部署到nginx本地,做第一层的业务逻辑

2、多级缓存架构中每一层的意义

1)nginx本地缓存,扛的是热数据的高并发访问,大量的热数据的访问,即经常会访问的那些数据,就会被保留在nginx本地缓存内。

2)redis分布式缓存,扛的是很高的离散访问,支撑海量的数据,高并发的访问,高可用的服务

3)tomcat 堆缓存主要是扛redis大规模灾难的

3、最经典的缓存+数据库读写的模式:cache aside pattern

1)Cache Aside Pattern

读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取出数据放入缓存

更新的时候,先删除缓存,再更新数据库

2)为什么是删除缓存,而不是更新缓存?

很多时候,复杂点的缓存场景,因为缓存有的时候,不简单是数据库中直接取出来的值,在更新操作较多的数据项上,访问到的几率还是比较少,没有必要每次进行更新的时候都对缓存进行修改

4、数据库与缓存双写,可能导致数据不一致的问题,围绕和结合实时性较高的库存服务,把数据库与缓存双写不一致的问题及其解决方案,给大家讲解一下

5、最初级的缓存不一致问题以及解决方案

问题:先修改数据库,再删除缓存,如果删除缓存失败了,那么会导致数据库中是新数据,缓存中是旧数据,数据出现不一致

解决思路:先删除缓存,再修改数据库,如果修改数据库失败了,那么数据库中是旧数据,缓存中是空的,因为读的时候缓存没有,则度数据库中的旧数据,然后更新到缓存中

6、比较复杂的数据不一致问题

数据发生了变更,先删除了缓存,然后要去修改数据库,此时还没修改,一个请求过来,去读缓存,发现缓存空了,去查询数据库,查到了修改前的旧数据,放到了缓存中

然后数据变更的程序完成了数据库的修改,则数据库和缓存中的数据不一样了。。。

7、高并发情况下数据一致性的解决方案——数据库与缓存更新与读取操作进行异步串行化

更新数据库的时候,根据数据库的唯一标识,将操作路由之后,发送到一个jvm内部的队列中

一个队列对应一个工作线程(根据商品ID取hash值并对队列个数取模值,确定入队信息)

每个工作线程串行拿到对应的操作,然后一条一条执行

这样的话,一个数据变更的操作,先执行,删除缓存,然后再去更新数据库,但是还没完成更新

此时如果一个读请求过来,读到了空的缓存,那么可以先将缓存更新的请求发送到队列中,此时会在队列中积压,然后同步等待缓存更新完成

这里有一个优化点,一个队列中,其实多个更新缓存请求串在一起是没有意义的,因此可以做过滤,如果发现队列中已经有一个更新缓存的请求了,

那么就不用再放个更新请求操作进去了,直接等待前面的更新操作请求完成即可。

8.高并发的场景下,该解决方案要注意的问题

1)读请求长时阻塞

如果缓存是空的,有两种情况,一是,数据库里本身就没有这条数据,这是可以判断一下该内存队列有没有数据库更新操作,如果没有数据库更新操作,说明这条数据可能压根就是空的,那么不用hang住,就返回空。

如果内存队列里,有这条商品的更新操作,hang一会儿,去等待那个操作快速完成,然后返回。

2)读请求并发量过高

3)多服务实例部署的请求路由

可能这个服务部署了多个实例,那么必须保证说,执行数据更新操作,以及执行缓存更新操作的请求,都通过nginx服务器路由到相同的服务实例上

        Service1                 Service2          Service3

对同一个商品的读写请求,全部路由到同一台机器上

nginx,hash路由的功能

4)热点商品的路由问题,导致请求的倾斜

万一某个商品的读写请求特别高,全部打到相同的机器的相同的队列里面去了,可能造成某台机器的压力过大

就是说,因为只有在商品数据更新的时候才会清空缓存,然后才会导致读写并发,所以更新频率不是太高的话,这个问题的影响并不是特别大

数据库和redis的一致性的更多相关文章

  1. Linux实战教学笔记45:NoSQL数据库之redis持久化存储(一)

    第1章 redis存储系统 1.1 redis概述 REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统.redis和大名鼎鼎的Mem ...

  2. 非关系型数据库(NOSQL)-Redis

    整理一波Redis 简介,与memcached比较 官网:http://redis.io Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括 ...

  3. NoSQL数据库:数据的一致性

    NoSQL数据库:数据的一致性 读取一致性 强一致性 在任何时间访问集群中任一结点,得到的数据结果一致: 用户一致性 对同一用户,访问集群期间得到的数据一致: 解决用户一致性:使用粘性会话,将会话绑定 ...

  4. python爬取大众点评并写入mongodb数据库和redis数据库

    抓取大众点评首页左侧信息,如图: 我们要实现把中文名字都存到mongodb,而每个链接存入redis数据库. 因为将数据存到mongodb时每一个信息都会有一个对应的id,那样就方便我们存入redis ...

  5. 数据库之redis篇(3)—— Python操作redis

    虽然前面两篇已经说了redis的一些配置安装什么的,篇幅有点长,可能看完了也不知道怎么操作,这里再浓缩一下: 什么是redis redis完全开源免费的,遵守BSD协议,是一个高性能的非关系型key- ...

  6. 阿里云、青云、腾讯云服务器,Mysql数据库,Redis等产品性能对比

    阿里云.青云.腾讯云服务器,Mysql数据库,Redis等产品都使用过,对比维度很多就不一一放出.直接放结论吧:买的腾讯(金融专区)服务器,Mysql(TDSql)把所有项目转到腾讯云,但是没有用腾讯 ...

  7. Python操作nosql数据库之redis

    一.NoSQL的操作 NoSQL,泛指非关系型的数据库.随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不 ...

  8. key-value键值型数据库:Redis

    key-value键值型数据库:Redis redis Redis是in-memory型(内存型)的键值数据库,数据在磁盘上是持久的,键类型是字符串,值类型是字符串.字符串集合(Set).sorted ...

  9. NOSQL数据库之 REDIS

    NOSQL数据库之 REDIS 一.NOSQL 1.简介 NoSQL ,(Not Only SQL),泛指非关系型数据库. 特点: NoSQL 通常是以key-value形式存储, 不支持SQL语句, ...

随机推荐

  1. 78. Subsets C++回溯法

    本题还是基本的回溯法.就是回溯函数的参数选择上要花点心思! class Solution { public: void backTrack(vector<int> ans, vector& ...

  2. 【LeetCode】成对交换节点

    e.g. 给定链表 1->2->3->4,返回 2->1->4->3 的头节点. 我写了个常见的从头节点遍历,少量的奇数个或偶数个数据都能成功重新排列.但链表过长时 ...

  3. Linux修改用户密码有效期

    linux默认用户的密码是永不过期的,但是出于安全考虑在企业环境中一般会要求设置过期日期:但有时要求90天就过期,在这种严柯条件下我们有可能想给某个或某些用户开设后门,延长其密码有效期. 一.用户密码 ...

  4. Java技巧之双括弧初始化

    由于Java语言的集合框架中(collections, 如list, map, set等)没有提供任何简便的语法结构,这使得在建立常量集合时的工作非常繁索.每次建立时我们都要做: 定义一个临时的集合类 ...

  5. Generative Model 与 Discriminative Model

      [摘要]    - 生成模型(Generative Model) :无穷样本==>概率密度模型 = 产生模型==>预测    - 判别模型(Discriminative Model): ...

  6. LY.猜字小游戏

    猜字小游戏

  7. laravel中的注册页面

    <?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; class RegisterCo ...

  8. 读入excle

    可以输出到csv(逗号间隔,具体搜索csv格式). csv可以在excel中直接导入. 也可以用system函数调用ssconvert从csv转xlsx:system("ssconvert ...

  9. 【Oracle安装卸载】oracle卸载

    Oracle卸载比较麻烦,不能简单卸载就完成了,有时没有卸载完整,下次安装不能很好的安装: 当然Oracle卸载也没有那么难,只是步骤比较多.Oracle10g还是Oracle11g卸载步骤都是一样的 ...

  10. day1 计算机硬件基础

    CPU包括运算符和逻辑符 储存器包括内存和硬盘 7200转的机械硬盘一般找到想要的数据需要9毫秒的时间      4+5   5毫秒的时间是磁头到磁盘轨道    4毫秒是平均开始查找想要的数据到找到的 ...