缓存学习笔记

缓存主要有Redis和memcached,工作中主要涉及Redis。
Redis是一个key-value存储系统。我们主要用到它的缓存机制,比如可以用来缓存用户信息,用于同一用户在不同系统之间进行登录。
如下定义引用百度百科:redis是一个key-value存储系统。它和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
https://baike.baidu.com/item/Redis/6549233?fr=aladdin
http://blog.csdn.net/linlzk/article/details/41801391
========================================
redis配置
1. 配置redis服务(在服务器上配置Redis服务)
2.配置redis的启动参数

    @Bean
    public JedisPool redisPoolFactory() {
        logger.info("JedisPool注入成功!!");
        logger.info("redis地址:" + host + ":" + port);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        if(StringUtils.isEmpty(password)){
             jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
        }else{
             jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout,password);
        }

        return jedisPool;
    }

3.调用redis服务

//将值value关联到key,并将key的生存时间设为seconds(秒)
String redis.clients.jedis.Jedis.setex(String key, int seconds, String value)
Jedis jedis = jedisPool.getResource();
jedis.setex(keystoneId, 3600, json);

======================
面试中可能遇到的问题?

======================

为什么会需要消息队列(MQ)?
主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update之类的请求同时到达MySQL,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。
通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。

======================

什么是缓存穿透?
一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

    /**
     * 检查给定 key 是否存在。
     * 可用版本:>= 1.0.0
     * 时间复杂度:O(1) 若 key 存在,返回 1 ,否则返回 0 。
     * 
     * @param jedis
     * @param key
     * @return 若 key 存在 ,返回true,否则返回false
     */
    public static boolean isExistsKey(Jedis jedis, String key) {
        return jedis.exists(key);
    }

https://blog.csdn.net/wang0112233/article/details/79558612

===========
什么是缓存雪崩?

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。

如何避免?
目前系统的方案是设置生存时间为永久(所在项目的解决方案,项目key值较少)
正常的避免方案—–
1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
2:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
3:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期(此点为补充)

https://blog.csdn.net/wang0112233/article/details/79558612

===========

如何保证redis缓存和mysql数据库同步?
公司项目为了保持强一致性,采用实时同步方案,即查询缓存查询不到再从DB查询,保存到缓存;更新缓存时,先更新数据库,再将缓存的设置过期(建议不要去更新缓存内容,直接设置缓存过期)。
在查询的时候,先去缓存中拿数据,如果拿不到,就写缓存。执行更新操作就删除缓存。
读操作就直接拿,写操作上分布式锁,把数据更新到redis里。

其他方案可参考大牛的文章【如何保证redis缓存和mysql数据库同步】
https://www.cnblogs.com/lanbo203/p/7494587.html

===========
redis和memcached的区别?
缓存rdb和aof的区别?
Redis的淘汰策略?

参考资料
redis初级教程
http://www.runoob.com/redis/redis-tutorial.html
Mac安装redis
http://www.cnblogs.com/chinesern/p/5580665.html
Redis
http://www.runoob.com/redis/redis-intro.html
http://www.runoob.com/redis/transactions-watch.html
https://www.cnblogs.com/Survivalist/p/8119891.html
https://blog.csdn.net/mlc1218559742/article/details/52670095
https://www.jianshu.com/p/824066d70da8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值