八张图了解Redis和MySQL数据一致性问题

前言首发公众号:bigsai 头条号:程序员bigsai 还请关注、一键三连!
对于Web来说,用户量和访问量在一定程度上推动项目技术和架构的更迭和进步 。可能会有以下的一些状况:

  1. 页面并发量和访问量并不多,MySQL足以支撑自己逻辑业务的发展 。那么其实可以不加缓存 。最多对静态页面进行缓存即可 。
  2. 页面的并发量显著增多,数据库有些压力,并且有些数据更新频率较低反复被查询或者查询速度较慢 。那么就可以考虑使用缓存技术优化 。对高命中的对象存到key-value形式的redis中,那么,如果数据被命中,那么可以不经过效率很低的db 。从高效的redis中查找到数据 。
  3. 当然,可能还会遇到其他问题,你还通过静态页面缓存页面、cdn加速、甚至负载均衡这些方法提高系统并发量 。这里就不做介绍 。

八张图了解Redis和MySQL数据一致性问题

文章插图
 
缓存思想无处不在我们从一个算法问题开始了解缓存的意义 。
问题1:
  • 输入一个数n(n<20),求n!;
分析1:
  • 单单考虑算法,不考虑数值越界问题 。当然我们知道n!=n * (n-1) * (n-2) * ... * 1= n * (n-1)!; 那么我们可以用一个递归函数解决问题 。
static long jiecheng(int n){ if(n==1||n==0)return 1; else {   return n*jiecheng(n-1); }}这样每输入求一次需要执行n次 。 问题2:
  • 输入t组数据(可能成百上千),每组一个xi(xi<20),求xi!;
分析2:
  • 如果使用递归,输入t组数据,每次输入为xi,那么每次都要执行次数为: 当每次输入的Xi过大或者t过大都会造成不小的负担!时间复杂度为O(n2)
  • 那么能否换个思想的 。没错、是打表 。打表常用于ACM算法中,常用于解决多组输入输出、图论搜索结果、路径储存问题 。那么,对于这个求阶乘 。我们只需要申请一个数组,按照编号从前往后将在需求的数存到数组中,后面再取得时候直接输出数组值就可以,思想很明确吧:
import JAVA.util.Scanner;public class test {public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc=new Scanner(System.in); int t=sc.nextInt(); long jiecheng[]=new long[21]; jiecheng[0]=1; for(int i=1;i<21;i++) {  jiecheng[i]=jiecheng[i-1]*i; }   for(int i=0;i<t;i++) {  int x=sc.nextInt();  System.out.println(jiecheng[x]); }}  }
  • 时间复杂度才O(n) 。这里的思想就和缓存思想差不多 。先将数据在jiecheng[21]数组中储存 。执行一次计算 。当后面继续访问的时候就相当于访问静态数组值 。每次都为O(1的操作) 。
缓存的应用场景缓存适用于高并发的场景,提升服务容量 。主要是将从经常被访问的数据或者查询成本较高从慢的介质中存到比较快的介质中,比如从硬盘—>内存 。我们知道大多数关系数据库是基于硬盘读写的,其效率和资源有限,而redis是基于内存的,其读写速度差别差别很大 。当并发过高关系数据库性能达到瓶颈时候,就可以策略性将常访问数据放到Redis提高系统吞吐和并发量 。
对于常用网站和场景,关系数据库主要可能放在两个地方:
  • 读写IO性能较差
  • 一个数据可能通过较大量计算得到
所以使用缓存能够减少磁盘IO次数和关系数据库的计算次数 。读取上速度快也从两个方面体现:
  • 基于内存,读写较快
  • 使用哈希算法直接定位结果不需要计算
所以对于像样的,有点规模的网站,缓存是很 necessary的,而Redis无疑是最好的选择之一 。
八张图了解Redis和MySQL数据一致性问题

文章插图
 
需要注意的问题缓存使用不当会带来很多问题 。所以需要对一些细节进行认真考量和设计 。当然最难得数据一致性在下面单独分析 。
是否用缓存项目不能为了用缓存而用缓存,缓存并一定适合所有场景,如果对数据一致性要求极高,又或者数据频繁更改而查询并不多,又或者根本没并发量的、查询简单的不一定需要缓存,还可能浪费资源使得项目变得臃肿难维护,并且使用redis缓存多多少少可能会遇到数据一致性问题需要考虑 。
缓存合理设计在设计缓存的时候,很可能会遇到多表查询,如果遇到多表查询缓存的键值对就需要合理考虑,是拆分还是合在一起?当然如果组合种类多但常出现的不多也可以直接缓存,具体的设计要根据项目业务需求来看,并没有一个非常绝对的标准 。


推荐阅读