<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                >[info] redis做緩存場景 1. 開銷大的復雜計算:以MySQL為例子,一些復雜的操作或者計算(例如大量聯表操作、一些分組計算),如果不加緩存,不但無法滿足高并發量,同時也會給MySQL帶來巨大的負擔。 2. String類型:計數器,緩存用戶對象,分布式鎖,session共享 3. List類型:不頻繁更新排行榜,消息隊列 4. Hash類型:購物車,緩存對象 5. Zset:實時排行榜,搶票加速包 6. Set類型:分庫分表之后減少復雜查詢,黑白名單,帥選功能等 ***** 圖左側為客戶端直接調用存儲層的架構,右側為比較典型的緩存層+存儲層架構。 ![](https://img.kancloud.cn/91/4f/914fab8e9b2ffe68c2ad80eb138bd625_1165x616.png) ***** >[info] 緩存維度劃分 **一張用戶表中有整整100個字段,那么我們在redis中該怎么去緩存這個用戶數據呢?** 1. 緩存全部數據 ``` Set(key,select * from user wgere id= xxx) ``` 2. 緩存部分數據 ``` Set(key,select 字段1,字段2,…字段n from user where id=xxx) ``` | 數據類型 | 通用性 | 空間占比 | 代碼維護 | | --- | --- | --- | --- | | 全部數據 | 高 | 大 | 簡單 | | 部分數據 | 低 | 小 | 復雜 | >[info] 緩存擊穿 緩存擊穿是指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由于并發用戶特別多,同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大,造成過大壓力。 ![](https://img.kancloud.cn/f3/26/f3269679c52cdaae1648c937c6fe991f_1190x531.png) ***** **為什么會出現緩存擊穿?** 一般在使用緩存去緩存數據時,會使用“緩存+過期時間”的策略既可以加速數據讀寫,又可以保證數據的定期更新,這個模式在一般情況的業務都是可以滿足的。 ***** **但是這樣也會出現兩個致命問題:** 1. 當前key是一個熱點數據(比如:某個熱門的文章,新聞),并發量非常大。 2. 重建緩存不能在短時間完成,可能是一個復雜的計算,例如復雜的sql,多次IO,多個依賴等。 ***** **在緩存失效的瞬間,有大量線程來重建緩存,造成后端負載加大,甚至可能讓應用崩潰,如果要解決這個問題至少是遵循如下:** 1. 減少重建緩存的次數 2. 數據盡可能一致 3. 較少的潛在威脅 ***** >[info] 緩存擊穿問題解決 **1. 互斥鎖** ![](https://img.kancloud.cn/c4/20/c42076c4705fa0251293dc06991cd801_1690x898.png) ``` <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Redis; use Illuminate\Support\Facades\DB; class TestController extends Controller { public function index(Request $request) { $userId = $request->input("user_id"); dd(json_decode($this->getArticle(1))); } public function lock($key,$random) { $lock = Redis::set($key,$random,"nx","ex",10); return $lock; } public function unlock($key,$random) { if (Redis::get($key) == $random){ Redis::del($key); } } public function getArticle($id) { $key = "article_content_".$id; $ret = Redis::get($key); if ($ret === null) { //生成鎖的key $lockKey = $key . '_lock'; //生成隨機數,用于設置鎖的值,后面釋放鎖時會用到 $random = mt_rand(); //拿到互斥鎖 if ($this->lock($lockKey, $random)) { //這里是偽代碼,表示從數據庫中獲取文章數據 $ret = json_encode(DB::table("article")->where("id",$id)->first()); //更新緩存,過期時間可以根據情況自已調整 Redis::set($key, json_encode($ret)); //釋放鎖 $this->unLock($lockKey, $random); } else { //等待200毫秒,然后重新獲取緩存值,讓其他獲取到鎖的進程取得數據并設置緩存 usleep(200); return $this->getArticle($id); } }else{ $ret = json_decode($ret); } return $ret; } } ``` **代碼解釋:** ~~~ 1. 從redis獲取數據,如果值不為空,則直接返回值,否則執行下面的步驟: 2. 如果set(nx和ex)結果為true,說明此時沒有其他線程重建緩存,那么當前線程執行緩存構建邏輯 2. 如果set(nx和ex)結果為false,說明此時已有其他線程正在執行構建緩存的工作,那么當前線程將休息指定時間后,重新執行函數,直到獲取到數據。 ~~~ ***** **2. key設置永不過期** 設置永不過期這里包含兩層意思: ``` 1. 從緩存層面來看,確實沒有設置過期時間,所以不會出現熱點key過期后產生的問題,也就是物理過期。 2. 從功能層面看,為每個value設置一個邏輯過期時間,當發現超過邏輯過期時間后,會使用單獨的線程去構建緩存。 ``` ***** 從實戰方面來說,設置熱點數據永不過期有效杜絕了熱點key產生的問題,但是不足的點在于重構緩存期間,會出現數據不一致性的情況,這種情況在應用中是堅決不允許出現的。 ![](https://img.kancloud.cn/3f/95/3f95f333a740339c9f81ec6d1157e041_1191x660.png) 解決數據不一致的問題可以是每次查詢的時候都去判斷下是否超時,超時就立刻更新緩存數據。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看