1. 程式人生 > >Redis的模糊查詢在生產環境出現嚴重的效能問題

Redis的模糊查詢在生產環境出現嚴重的效能問題

這裡寫圖片描述
Redis是一個高效能高效率的key-value儲存的nosql資料庫,由於資料是儲存在記憶體中,因此訪問速度非常快,由於專案涉及到資料庫的查詢非常多,而資料變大並不是非常頻繁,所以在專案中採用Redis分擔大部分MySQL的壓力。

在專案中實際使用我用的Redis提供的客戶端連線工具包jedis,在專案中引入jedis.Jar即可

 1public static Set<String> searchLike(String like_key) {
 2    //線上環境模糊查詢帶來嚴重的效能問題,杜絕使用
 3    if(!Config.IS_BUG){
 4        return
null; 5 } 6 Jedis jedis = RedisApi.getJedis(); 7 boolean is_ok = true; 8 try { 9 if (jedis == null) { 10 return null; 11 } 12 return jedis.keys(like_key); 13 } catch (Exception e) { 14 // TODO: handle exception 15 is_ok = false; 16 return
null; 17 } finally { 18 close(jedis, is_ok); 19 } 20}

每當使用者登入成功之後,都會生成一個cookie,分別存在客戶端和Redis資料庫,cookie的key由cookie值+使用者ID組成:cookie字串+”_”+使用者ID,

例如使用者cookie為“d9fb0ea5955fcf0a2183c5076”,使用者ID為 19092,

那Redis中儲存的key就是 d9fb0ea5955fcf0a2183c5076_19092,最終的key-vlaue就是:

1{“d9fb0ea5955fcf0a2183c5076_19092”:d9fb0ea5955fcf0a2183c5076}
而在使用者不斷的登入成功,就不斷地產生這樣的記錄,久而久之,會積累出非常多的無用的key,浪費redis的空間,也加重了redis查詢的負擔,因此想到使用Redis的模糊查詢來清掉無用的cookie的key

而Redis的客戶端jedis操作是通過jedis.keys(keys)來完成的,keys可以使用萬用字元來匹配Redis中的key

萬用字元說明:

: 0到任意多個字元 eg: searchLike(“test“)

?: 1個字元

比如現在需要清除某個使用者所有的無用的cookie的key,,則可以寫成“ *_19092 ”

1    String key_like = "*_19092";
2    Set<String> keys = RedisApi.searchLike(key_like);

這樣就可以查出所有這個使用者的keys,呼叫jedis提供的批量刪除key的方法即可達到目的。

1 String key_like = "*_19092";
2 Set<String> keys = RedisApi.searchLike(key_like);

到這裡從需求到邏輯到編碼一氣呵成,簡單測試沒什麼問題後,就釋出到線上,由於平時網站的流量不算非常高,所以運行了幾天也沒發生什麼異常,直到今天早上,擁有幾十萬粉絲的公眾號發推文,推文的內容直接連結到網站,因此說瞬間流量是非常高

這裡寫圖片描述

運行了大約十分鐘之後,運營突然發瘋的過來說網站訪問非常慢,甚至出現錯誤碼,心裡一慌,趕緊上去看日誌,我了個乖乖啊,簡直是嚇人,error日誌想流水一樣蹦出來,但五一不例外都是下面圖示的錯誤:從Redis池中獲取不大連線數,馬上上redis伺服器檢視,發現CPU已經到達了100%以上

這裡寫圖片描述

能讓Redis的CPU到100%的,我想出了一下幾個可能:

連線數過多,佔用連線的時間過長

儲存的值過大,存取均很佔用CPU和記憶體

慢查詢,事其它操作等待時間超時

redis阻塞,某個操作把Redis阻塞,導致CPU飆升

由於專案上線時間已經很久,前三個可能基本都在平時檢視Redis伺服器效能的過程中排除掉,因此很大概率是第四個,突然想起前幾天做的功能,有個模糊查詢,該不是這個問題吧?我到網站輸入“Redis 模糊查詢 效能”,出來非常多關於redis模糊查詢效能急劇下降的的情況,而且建議生產環境下禁用redis的模糊查詢,於是我把模糊查詢這塊業務直接註釋掉,重新上線,運行了半天,再沒出現這個問題,因此可以斷定就是模糊查詢搞的鬼。

【替代方案】

有問題肯定是要解決的,既然模糊查詢行不通的,那就得想別的辦法達到目的,想到Redis有Set這這種儲存結構,因此可以把使用者的所有cookie key都放到一個使用者專屬的Set中,每次使用者登入成功之後,都把之前Set裡的cookie key清除,然後再把最新的key放進去,這樣就可以達到同樣的目的了。

 1 String setKey = "prefix_customer_cookie_list_10920";
 2        String token="ss2ssssss";
 3        //取出所有的使用者的cookie key
 4        Set<String> list = RedisApi.getSet(setKey);
 5        if (list != null && list.size() > 0) {
 6            //刪除使用者所有的cookie key
 7            RedisApi.removeFromSet(setKey, list.toArray(new String[0]));
 8        }
 9        //把最新的cookie key加入到Set中
10        RedisApi.addSet(setKey, token);

欲知大流量下的效果如何,請關注我哦,下回發推文後回覆你哦

覺得本文對你有幫助?請分享給更多人

關注「程式設計無界」,提升裝逼技能

這裡寫圖片描述

相關推薦

Redis模糊查詢生產環境出現嚴重效能問題

Redis是一個高效能高效率的key-value儲存的nosql資料庫,由於資料是儲存在記憶體中,因此訪問速度非常快,由於專案涉及到資料庫的查詢非常多,而資料變大並不是非常頻繁,所以在專案中採用Redis分擔大部分MySQL的壓力。 在專案中實際使用我用的

8. Redis 持久化對生產環境的災難恢復的意義

redis持久化 恢復 存儲 bubuko 區別 同學 inf 全部 企業 1、故障發生的時候會怎麽樣2、如何應對故障的發生 很多同學,自己也看過一些redis的資料和書籍,當然可能也看過一些redis視頻課程 所有的資料,其實都會講解redis持久化,但是有個問題,我到目

生產環境下的效能監控

排查效能問題往往比排查功能性的Bug更讓人頭疼,主要有以下幾個原因 很多效能問題只會在高負載的生產環境下出現,在開發過程中很難發現。 功能性出錯時我們通常會丟擲異常,我們可以通過Tracestack很快定位到問題所在程式碼的位置。但對於效能問題,我們很難做這樣的快速定位。 雖然我

生產環境出現Bug,應該如何部署Hotfix?

 今天早上,有同事問我部署的問題,說HotFix應該如何部署?在我的博文《業主說我們專案經理上線很隨意,“愛發就發”!》一文中,我已經做了介紹,建議讀者先讀一下該博文,但是可能我沒有針對性地將HotFix應該如何部署。 如何部署Hotfix呢?首先我們要了解生產環境的版本,

假設生產環境出現CPU佔用過高,請談談你的分析思路和定位

0、top 1、檢視佔用cpu大的程序 jps -l 或者 ps -ef|grep java|grep -v grep&n

vue 生產環境build打包出現空白頁面的解決方法

uil run conf htm clas -c hunk con npm vue 生產環境build打包出現空白頁面的解決方法: 如果出現:webpackjsonp is not defined 因為公共文件必須在引用js之前引用。只需要在build 文件下webpack

生產環境redis備份與恢復

day 更新 word bsd bin err 大小 簽到 文件 redis是一個開源(BSD許可),內存存儲的數據結構服務器,可用作數據庫,高速緩存和消息隊列代理。生產中我們主要用來存儲用戶的登錄信息,設備的詳情數據,以及會員簽到點贊的信息等等。下面來記錄下生產中redi

生產環境實踐:redis高可用架設

rediskeepalived 經過測試,當主redis停掉的時候,可以5秒鐘內切換到從redis,反之切換到主,也是一樣的時間。 在A服務器(192.168.16.29),B服務器(192.168.16.2)上均安裝redis,keepalived。 A作為默認的master,B作為sla

[備忘] redis 生產環境配置

轉載自:http://blog.chinaunix.net/uid-30111490-id-4819701.html redis配置詳解 # 預設情況下,redis不是在後臺模式執行的,如果需要在後臺程序執行,把該項的值更改為yes,預設為no  daemonize no&n

Redis 資料庫keys 命令的模糊查詢

文章目錄 Redis 資料庫keys 命令的模糊查詢 1、支援的萬用字元 2、* 萬用字元 3、?萬用字元 4、[ ]匹配

單機版的redis的安裝以及redis生產環境啟動方案

▌大綱 1、安裝單機版的redis 2、redis的生產環境啟動方案 3、redis cli的使用   ▌1、安裝單機版redis wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz tar -zx

雲端計算生產環境架構效能調優和遷移套路總結(以 AWS 為例)

最近完成了一個雲端計算平臺應用的架構調優。客戶是一個 Wordpress + MySQL 的站點,剛從本地資料中心遷移到了 AWS,由於團隊技能限制,無法充分發揮雲端計算的優勢。加之應用程式在夜間高流量時段崩潰,架構優化和遷移迫在眉睫。本文以這次架構遷移經驗為例,介紹雲端計算架構優化遷移的基本步驟和

JDK8的GC型別 與 高併發生產環境中不同GC型別帶來的效能提升

    記一次專案中,在JDK8環境下,並行GC月併發GC在Restful介面中體現差異。     當今國內第三大流量電商(某多多),博主所在公司在前一段時間和他們有產品合作,他們對我們產品提出了非常嚴格的要求:一分鐘時間範圍內介面響應時間大於300MS的

[JVM]Java生產環境效能監控與調優詳解_Btrace

本章關鍵詞:BTrace、攔截、注意事項 一、入門 1.做什麼的? 可以在應用程式不重啟,不修改的情況下,正在執行的情況下,動態的修改位元組碼,達到監控除錯的目的 可以動態的向目標應用程式的位元組碼注入追蹤程式碼 用到的技術 JavaComplierApi、J

[JVM]Java生產環境效能監控與調優_參考文件連結

第二章 jdk8工具集 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.html Troubleshooting https://docs.oracle.com/javase/8/doc

Java生產環境效能監控與調優詳解

第8章 JVM位元組碼與Java程式碼層調優 本章帶大家學習JVM的位元組碼指令,從位元組碼層面講解一些常見問題的底層原理(面試能回答上的話, 絕對加分),比如:i++和++i哪一種效率高?迴圈體中做字串+拼接為什麼效率低?然後會重點對String做講解,包括String常量池的變化、String字面

prometheus+grafana 監控生產環境機器的系統資訊、redis、mongodb以及jvm

介紹:       為了更好的對生產環境的一些中介軟體和作業系統的執行情況進行視覺化的展示,近期瞭解了下prometheus加上grafana來實現這種效果,由於prometheus是新出來的開源專案,所以,監控的外掛還不是很多,但是對基本的一些需求能夠滿足。     Prometheus 是源於 Googl

轉載 -- NodeJs【生產環境】最佳實踐:效能和可靠性

// expressjs.com   // Production best practices: performance and reliability  看過了,基本理解 // 這篇文章是expressjs官網的文章,非常棒,回答了用nodejs的過程中的一些

基於redis的分散式鎖(不適合用於生產環境

1 介紹 這篇博文講介紹如何一步步構建一個基於Redis的分散式鎖。會從最原始的版本開始,然後根據問題進行調整,最後完成一個較為合理的分散式鎖。 本篇文章會將分散式鎖的實現分為兩部分,一個是單機環境,另一個是叢集環境下的Redis鎖實現。在介紹分散式鎖的實現之前,先來了解下分散式鎖的一些資訊。 2

Spark Streaming效能優化: 如何在生產環境下動態應對流資料峰值

1、為什麼引入Backpressure      預設情況下,Spark Streaming通過Receiver以生產者生產資料的速率接收資料,計算過程中會出現batch processing time > batch interval的情況,其中batch