緩存學習筆記

緩存主要有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

發佈了143 篇原創文章 · 獲贊 54 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章