缓存与DB一致性问题
缓存是什么缓存(cache):原始意义是指访问速度比一般RAM快的一种高速存储器,等等拿错剧本了。我们今天要说的是关于JavaWeb中使用的缓存,并不是计算机组成里面的缓存。在Java中常用redis数据库,memcache数据库等内存数据库去代替。因为它相对硬盘(持久化)数据库MySQL要快好多(当然MySQL也有自己的缓存,我们这边不展开)。所以一般我们使用这种数据库用于存放一些热点数据或者临时数据。
缓存的作用缓存的主要作用就是提高系统性能。特别是在热点数据比较多,而且读操作远大于写操作的时候。当一个读数据请求访问到应用,应用就不需要请求其他应用或者数据库。直接从缓存获取,从而提高了系统性能。但是从缓存中读取数据有好处,也有不好的,不好的就是可能会出现DB数据与缓存数据不一致的问题。所以如何保证缓存与DB数据致的问题,就是我们下面要聊的。
缓存与DB读写的流程缓存从数据库中读取数据,一般分三个步骤
1、先从缓存中读取,如果命中缓存,数据直接返回。
2、如果缓存中没有读取带数据,直接访问DB
3、从DB读取数据之后,回写到缓存中。
在数据库写数据时操作过程
1、淘汰缓存中的数据记 ...
Spring事务浅谈
Spring事务浅谈什么是事务简单点来说,就是一组被包装过的操作(一般是更新数据库,插入或者更新多个库的操作,一般读数据库不需要事务,都是在写操作的时候)。包装过的这些操作是可以回滚的。简单点说,就是这组操作中有一个或者失败,就全体失败回滚,只有全部成功才能才算执行完成。(比较大白话),事务是一个不可分割操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态变到另一种一致性状态。一般事务会有四个属性(ACDI)原子性,一致性,隔离性,持久性。具体详细的内容我之前博客是有的详细的介绍。事务
Spring的事务管理上面说的事务,是事务的基本概念,一般事务多与数据库相关,比如mysql,jdbc等等都有对事务的支持。但是除了数据库,随着机器的不断增多,越来越多的分布式事务出现了。比如现在比较常用的方式就是使用事务的mq,来实现分布式事务的。也有什么两步提交,三步提交理论。我们不详细的展开了。这里我们重点是说Spring对事务的管理。Spring没有事务,他只是抽象出对事务的管理接口TransactionManager,然后其他组件(jdbc)去实现spring的接口 ...
布隆过滤器
什么是布隆过滤器布隆过滤器(Bloom Filter),是1970年由布隆提出的。它是由一个很长的二进制向量和一系列映射函数组成。本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。
图中的,映射函数就是hash1(),hash2(),hash3()就是映射函数。下面的存放的就是一个超长二进制向量。一个数通过三次计算,映射到三个不同的地方。这个就是存储过程。
还有一个就是判断,就是根据过来的值,再去hash三次,看是否能在二进制向量上找到存在的值。如果三次都是1,说明这个值可能存在,反之是一定不存在。也就是说布隆过滤器上,如果存在(不一定真的存在,可能是冲突)。如果不存在那就一定不存在。所以一般使用都是通过这一个不存在的这个特性去处理。用英语说:False is always false. True is maybe true。
相比于传统的 List,Tree,Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不 ...
dubbo的hessian序列化的坑
什么是序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。一般这个过程分两部分,一个是序列化,一个是反序列化。(这样说不便理解,我下面做一个简单的比喻)。
比如把一块肉和一本书,通过一个很细的管子传递到别的地方。(网络传输是字节流)
1、传肉的话要把肉切碎了传,到管子的另一边就成肉馅了。这个是不可被序列化的结果。
2、传书的话可以把书一页一页的撕下来卷成纸筒传过去,都传完之后按照页数排列好订在一起。这个是可被序列化的结果。(把书编页码,然后撕下来,这个是序列化过程。接收到在把书按照页数钉装在一起这个过程是反序列化)
一般Java中实现序列化都要去实现Serializable接口,同时也会有一个uuid。这个uuid一般都是自动生成的,这个主要用于反序列化时候区分版本的作用。
上面看上去那么麻烦,实现序列化,那为什么要实现序列化,实现序列化有什么好处。
为什么要序列化先说好处,然后在解释。
1、序列化方便了网络数据的传输,可以通过序列 ...
函数式编程与Java的Lambda
什么是函数式编程什么是函数式编程函数式编程(functional programming):或称函数程序设计,又称泛函编程,是一种编程范式,它将计算机运算视为数学上的函数计算,并且避免使用程序状态以及易变对象。函数编程语言最重要的基础是λ演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。
比起指令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。函数式编程是偏结构化的编程。
如果看到上面你感觉没懂,或者一脸懵逼。那就对了,上面是非常抽象的,书面的表达;相对来说不是那么容易理解。所以我们要换个方法一点一点的带入。首先从上面提到一个指令式编程,根据这个对比我们看起来会相对容易理解。指令式编程又叫命令式编程,我们一般接触这种类型的语言多一点,比如说C,C++,JAVA很多语言都是命令式编程。我们现在引入命令式编程的概念。
什么是命令式编程命令式编程(Imperative programming):是一种描述计算机所需作出的行为的编程范式。机 ...
一致性Hash算法与Java的简单实现
重提Hash你会发现,在编程的这个领域里面Hash是经常被提及的一个词,我们经常使用比如HashMap,HashSet等等都是与Hash有关,之前我也写过一篇关于HashMap的简介,就是简单的介绍一下Hash,那么我们现在又开始聊Hash一致性算法。这个也是和Hash有关。
之前我们提及Hash其实就是做一个映射,把一个比较大的集合,或者一个比较复杂的集合,映射到一个比较简单的集合。这个过程叫Hash,这样我们在这个简单的集合实现一些运算比较容易。这是一种比较简单的说法,但是实际上真正的Hash要比这个复杂,Hash算法叫散列值算法。
散列函数是任何函数可被用于映射数据任意大小的为固定大小的数据。散列函数返回的值称为散列值,散列码,摘要或简单的散列。在HashMap中一般这个散列码就是数组中数组下标。但是这个散列码也就是我们经常说的HashCode。估计这个时候有人会问hashCode一直的两个对象相等吗。一般来讲HashCode相等的两个对象一般不等,而相等的两个对象HashCode一定相等。毕竟Hash算法一般是有冲突的,所以HashMap中是使用数组+链表(拉链)的形式来解决冲 ...
浅析UnSafe
UnSafe类 UnSafe是一个类,它存放于package sun.misc;是Java的一个基本类。看这个包名应该是属于BootStrap加载器加载的类。其次他是一个public final class Unsafe {}Final的类,他不能被直接的new 出来而是通过反射的方式获取到(后面会有代码做演示)。同样它也不能被继承,所以一般情况下我们在做应用开发的时候很少会使用到这类,但是这个类却在很多框架和并发包中大量的使用,所以想深入的了解Java还是要知道一些关于UnSafe类的知识。
从这个类的名字Unsafe上来说这个类就是一个不安全的类,也是不开放给用户直接使用的(当然我们还是可以通过其他一些方法用到)。这个类在jdk源码中多个类中用到,主要作用是任意内存地址位置处读写数据,外加一下CAS操作。它的大部分操作都是绕过JVM通过JNI(Java Native Interface)完成的,因此它所分配的内存需要手动free(因为绕过了JVM所以就没有垃圾回收),所以是非常危险的(容易内存泄漏)。但是Unsafe中很多(但不是所有)方法都很有用,且有些情况下 ...