redis
数据类型丰富
支持数据磁盘持久化存储
支持主从
支持分片
为什么redis快
完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
数据结构简单,对数据操作也简单
采用单线程,单线程也能处理高并发请求,想多核也可启动多实例
使用多路i/o复用模型,非阻塞i/o
redis数据类型
string:最基本的数据类型,二进制安全
hash:string元素组成的字典,适用于存储对象
list:按照string元素插入顺序排序
set:string组成的无序集合,通过hash表实现,不允许重复
sorted set:通过分数来为集合中的成员进行从小到大的排序
用于计数的hyperloglog,用于支持存储地理位置信息的geo
redis分布式缓存
- 获取锁时,使用setnx加锁,锁的value值为一个随机生成的uuid,在释放锁的时候进行判断,使用expire命令为锁添加一个超时时间,超过时间自动释放锁。
- 释放锁通过uuid,若是,用delete进行锁释放
redis异步队列
使用list作为队列,rpush生产消息,lpop消费信息
缺点:没有等待队列里有值就直接消费
弥补:在应用层引入sleep机制去调用lpop重试
blpop key timeout:阻塞知道队列有消息或者超时
缺点:只能供一个消费者消费
pub发送者/sub订阅者
缺点:消息的发布是无状态的,无法保证可达
redis持久化
- rdb快照持久化:保存某个数据点的全量数据快照,save:阻塞redis服务器进程,知道rdb文件被创建完毕,bgsave:fork出一个子线程来船舰rdb文件,不阻塞服务器进程
- 根据redis.conf配置里的save m n定时触发
- 主从复制时,主节点自动触发
- debug reload
- 执行shutdown且没有开启aof持久化
rdb持久化缺点:
内存数据的全量同步,数据量大会由于i/o严重影响性能
可能会因为redis挂掉而丢失从当前至最近一次快照期间的数据
aof持久化:日志重写解决aof文件大小不断增大的问题,原理如下(调用fork(),创建一个子进程,子进程把新写的aof写到一个临时文件里,不依赖原来的aof文件,主进程持续将新的变动写到内存和原来的aof,主进程获取子进程重写aof的完成信号,网aof同步增量变动,使用新的aof文件替换旧的aof文件)
rdb和aof优缺点
rdb优点:全量数据快照,文件小,恢复快
rdb缺点:无法保存最快一次快照之后的数据
aof优点:可读性高,适合保存增量数据,数据不易丢失
aof缺点:文件体积大,恢复时间长
使用pipeline的好处
pipeline和linux管道类似
redis基于请求/响应模型,单个请求处理需要一一应答
pipeline批量执行指令,节省多次io往返时间
redis下载地址:https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100
运行:redis-server.exe redis.windows.conf
redis-cli.exe -h 127.0.0.1 -p 6379
服务命令
redis-server --service-install redis.windows-service.conf --loglevel verbose
redis相当于一个数据库,数据存在内存中,用于缓存
使用 redis 或 memcached 之类的称为分布式缓存,在多例时,各实例共用一份缓存数据,缓存具有一致性,但是具有复杂度
单线程,采用 IO 多路复用机制同时监听多个 socket,根据 socket 上的事件来选择对应的事件处理器进行处理。Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持简单的数据类型,String。Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中。
集群模式:memcached没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 redis 目前是原生支持 cluster 模式的.
Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的多路 IO 复用模型。
redis 持久化机制:
Redis的一种持久化方式叫快照(snapshotting,RDB),另一种方式是只追加文件(append-only file,AOF)。
Redis创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis性能),还可以将快照留在原地以便重启服务器的时候使用。
原文链接:https://blog.csdn.net/qq_34337272/article/details/80012284
memcached
代码层次类似hash
支持简单数据存储
不支持数据持久化存储
不支持主从
不支持分片
安装为服务 增加参数即可 memcached.exe -d install
使用的默认端口号是11211 ,设置端口,还有很多参数,设置内存大小等
C:\Users\dashi.lu>netstat -ano | findstr “11211”
TCP 0.0.0.0:11211 0.0.0.0:0 LISTENING 3308
TCP [::]:11211 [::]:0 LISTENING 3308
UDP 0.0.0.0:11211 : 3308
UDP [::]:11211 : 3308
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>spymemcached</artifactId>
<version>2.8.4</version>
</dependency>
memcached应用场景介绍
比如 用户登陆或者注册 验证码
缓存中储存在是一些非业务必要数据(不是一些紧要的数据)
memcached查看工具[无需记忆命令]
http://www.treesoft.cn/dms.html
一级缓存
也称之为sqlsession缓存,作用域比较小
特点 【hashmap不可卸载,有办法设置存活实践更小】
默认配置
<!--全局设置-->
<settings>
<!--一级缓存设置-->
<!--默认已经设置好了-->
<setting name="localCacheScope" value="SESSION"/>
</settings>
//
//同一个sqlsession,多次查询,共享一级缓存
SqlSession sqlSession = sqlSessionFactory.openSession();
AccountMapper mapper = sqlSession.getMapper(AccountMapper.class);
Account account1 = mapper.selectByPrimaryKey(22);
System.out.println(JSON.toJSONString(account1,true));
Thread.sleep(10000);
Account account2 = mapper.selectByPrimaryKey(22);
System.out.println(JSON.toJSONString(account2,true));
Account account3 = mapper.selectByPrimaryKey(22);
System.out.println(JSON.toJSONString(account3,true));
mybatis一级缓存的生命周期和sqlsession一致【sqlsession,localcache】
mybatis一级缓存内部实现是hashmap
如果有多个sqlsession对同一条数据进行操作,可能出现数据脏读的情况。
如果解决这个问题
另外在获取sqlsession的时候为自动提交模式 SqlSession sqlSession = sqlSessionFactory.openSession(true);
每一次都会查询数据库
二级缓存
跨sqlsession级别的缓存,作用域较大
特点【默认实现也是一个hashmap】
实际的应用场景是 用户查询 新闻id =1 信息,用户2 查询 新闻id=1 信息
,这里所说的用户对应代码就是不同的sqlsession,在不同的sqlsession中共享数据就是二级缓存
<!--开启二级缓存 默认就是开启的-->
<setting name="cacheEnabled" value="true"/>
//
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-memcached -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-memcached</artifactId>
<version>1.0.0</version>
</dependency>
//
编写memcached.properties 框架会在classes目录下默认寻找
#any string identifier
org.mybatis.caches.memcached.keyprefix=_biz-cache-wk_
#space separated list of ${host}:${port}
org.mybatis.caches.memcached.servers=127.0.0.1:11211
#org.mybatis.caches.memcached.servers=192.168.0.44:12000
#Any class that implementsnet.spy.memcached.ConnectionFactory
org.mybatis.caches.memcached.connectionfactory=net.spy.memcached.DefaultConnectionFactory
#the number of seconds in 30 days the expiration time (in seconds)
org.mybatis.caches.memcached.expiration=6000
#flag to enable/disable the async get
org.mybatis.caches.memcached.asyncget=false
#the timeout when using async get
org.mybatis.caches.memcached.timeout=5
#the timeout unit when using async get
org.mybatis.caches.memcached.timeoutunit=java.util.concurrent.TimeUnit.SECONDS
#if true, objects will be GZIP compressed before putting them to
org.mybatis.caches.memcached.compression=false
#\u7f13\u5b58\u670d\u52a1\u5668\u5b95\u673a\u540e\u591a\u4e45\u4e0d\u4f7f\u7528memcached \u6beb\u79d2\u4e3a\u5355\u4f4d
#refuse time when connection refused
org.mybatis.caches.memcached.refuseperiod=1000
//
//不同的sqlsession如果没有调用commit方法二级缓存并无作用
SqlSession sqlSession = sqlSessionFactory.openSession(true);
SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
AccountMapper mapper = sqlSession.getMapper(AccountMapper.class);
AccountMapper mapper2 = sqlSession2.getMapper(AccountMapper.class);
Account account1 = mapper.selectByPrimaryKey(5);
System.out.println(JSON.toJSONString(account1, true));
System.out.println("========================================");
Account account3 = mapper2.selectByPrimaryKey(5);
System.out.println(JSON.toJSONString(account3, true));
一级缓存和二级缓存的区别
一级缓存
**Mybatis的一级缓存是指Session缓存。**一级缓存的作用域默认是一个SqlSession。Mybatis默认开启一级缓存。 实现在同一个会话中数据的共享
也就是在同一个SqlSession中,执行相同的查询SQL,**第一次会去数据库进行查询,并写到缓存中;
第二次以后是直接去缓存中取。
Statement级别的缓存,可以理解为缓存只对当前执行的这一个Statement有效,执行完后就会清空缓存
当执行SQL查询中间发生了增删改的操作,MyBatis会把SqlSession的缓存清空。
一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION,如果不想使用一级缓存,可以把一级缓存的范围指定为STATEMENT,这样每次执行完一个Mapper中的语句后都会将一级缓存清除。
如果需要更改一级缓存的范围,可以在Mybatis的配置文件中,在下通过localCacheScope指定。
当Mybatis整合Spring后,直接通过Spring注入Mapper的形式,如果不是在同一个事务中每个Mapper的每次查询操作都对应一个全新的SqlSession实例,这个时候就不会有一级缓存的命中,但是在同一个事务中时共用的是同一个SqlSession。
如有需要可以启用二级缓存。
二级缓存
是指mapper映射文件,作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。
SqlSessionFactory级别的缓存,实现不同会话中数据的共享,是一个全局变量
当开启缓存后,数据的查询执行的流程就是二级缓存-> 一级缓存 -> 数据库
Mybatis需要手动设置启动二级缓存。
二级缓存是默认启用的(要生效需要对每个Mapper进行配置),如想取消,则可以通过Mybatis配置文件中的元素下的子元素来指定cacheEnabled为false。
<settings>
<setting name="cacheEnabled" value="false" />
</settings>
原文链接:https://blog.csdn.net/qq_26525215/article/details/79182637