Laravel - Redis 緩存三部曲 (二) Predis -基本數據隔離


Laravel - Redis 緩存三部曲 (二) Predis -基本數據隔離

上一篇 Redis三部曲(一)介紹了Laravel中Predis的幾種基本數據類型的使用和Redis的概念,但是就算會寫了,然而緩存什么時候使用呢???

下面就結合上一篇的內容給大家說說Predis的一些組合用法,隊列如何配合STRING類型或者HASH類型來組合使用,甚至把非關系變成和MySQl一樣成為關系型的。

隊列與哈希的組合使用 - 實現數據關系化

思路 :利用隊列里的值來做需要取數據的唯一索引,利用哈希的key的后綴名做原型數據的唯一索引

隊列和哈希的組合使用優勢是,取出來可以直接使用,劣勢在於內存占用相比較字符串而言要大

  • 實例:因為Redis只能存數組而我們實例為了方便直接用DB類來寫的,如果是ORM可以直接返回數組的
/** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $where = ['status'=>'1']; $obj = \DB::table('data_admin_login')->where($where)->get(); $array = $this->objectToArray($obj); dd($array); } 

打印的數據如下:

https://www.blog8090.com | 打印結果

  • 接下來 我們要把從數據庫取出來的數據存入Redis,用什么樣的方法存,用什么樣的方法取,這些東西都得考慮好;下面實例如下:
/** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $where = ['status'=>'1']; $obj = \DB::table('data_admin_login')->where($where)->get(); $array = $this->objectToArray($obj); // 定義Redis的key $listKey = 'LIST:TEST:ADMIN'; $hashKey = 'HASH:TEST:ADMIN:'; // 遍歷時寫入Redis list為索引 hash為數據 foreach($array as $v){ \Redis::rpush($listKey,$v['guid']); \Redis::hMset($hashKey.$v['guid'],$v); } return '緩存寫入成功'; } 
  • 查看下redis里面的情況 第一個 查看所有key 發現有1個隊列和16個哈希

第二個 取LIST:TEST:ADMIN 整個隊列 發現有16個 唯一識別ID的數據(而且順序和從數據庫取出來的順序是一樣的)

第三個取出其中一個哈希查看數據

https://www.blog8090.com | 終端顯示

  • 可以看出來 我們想要的數據已經存入了redis中,接下來,如果我想通過redis直接獲取MySQL中管理員的列表數據怎么使用呢?
/** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // // 定義Redis的key $listKey = 'LIST:TEST:ADMIN'; $hashKey = 'HASH:TEST:ADMIN:'; // 取出admin隊列的唯一識別id數組 $list = \Redis::lrange($listKey,0,-1); $array = null; foreach($list as $v){ // 取出哈希里的數據寫入大數組中 $array[] = \Redis::hGetall($hashKey.$v); } dd($array); } 
  • 我們來看看打印的結果

Https://www.blog8090.com | 打印結果

這樣取出來的數據是不是一樣可以遍歷到模版上?

  • 最后來完整的做一個例子

思路:我們的目的是從redis里面取出想要輸出到模版上的數據,但是redis大家也知道,只是緩存服務器重啟了,就沒了(除非做磁盤持久化),但是我要做的是如果Redis里面沒有我要從MySQL里面取,取到了然后寫入Redis,保證對MySQL的請求大大減少。

/** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // // 定義Redis的key $listKey = 'LIST:TEST:ADMIN'; $hashKey = 'HASH:TEST:ADMIN:'; // 查看key是否存在? if(empty(\Redis::exists($listKey))){ // 如果Redis不存在 讀數據庫然后寫入redis $where = ['status'=>'1']; $obj = \DB::table('data_admin_login')->where($where)->get(); $array = $this->objectToArray($obj); // 遍歷時寫入Redis list為索引 hash為數據 foreach($array as $v){ \Redis::rpush($listKey,$v['guid']); \Redis::hMset($hashKey.$v['guid'],$v); } return $array; } // 如果redis存在 直接讀redis的數據 // 取出admin隊列的唯一識別id數組 $list = \Redis::lrange($listKey,0,-1); $array = null; foreach($list as $v){ $array[] = \Redis::hGetall($hashKey.$v); } return $array; } 
  • 不管我把rediskey手動刪除還是rediskey存在 我們輸出的都是這個(這是我的瀏覽器插件json-handle的效果)

https://www.blog8090.com | 打印數據

  • 刪除rediskey 效果依舊

alt

那么肯定有人又要問了 你這只是在讀數據庫 如果我增 刪 改 后 redis不同步了哇

是這樣的,所以一般我們在實際商業項目中 做一個大型的redis數據隔離都需要把mysql的增刪改 綁上同步的redis操作,這樣下來,我每次讀redis既大大的提升了性能,也保障了數據的同步性

下面拿添加做一個實例,如何MySQLredis數據同步

restfulApi 添加方法

/** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // // 定義Redis的key $listKey = 'LIST:TEST:ADMIN'; $hashKey = 'HASH:TEST:ADMIN:'; $data = [ 'guid'=> '12341234123412341234123412341234', 'email'=> 'adminadmin@163.com', 'password'=> '111dcfeb6d42b320d9b885f1b8fa498a', 'status'=> '1', 'sroce'=> '0', 'addtime'=> time(), 'logintime'=> '', 'ip'=> '' ]; $temp = \DB::table('data_admin_login')->insert($data); if($temp){ \Redis::rpush($listKey,$data['guid']); \Redis::hMset($hashKey.$data['guid'],$data); return '寫入成功'; } return '寫入失敗'; } 
  • 頁面響應

alt

  • redis查看一下有沒有同步寫入

我們發現數據同步進入了redis

alt

  • index方法代碼不變 再請求一次 數據也明顯同步了

alt

以上講的就是最基本的redis隔離技術,當然為了提現的簡單點,直接都寫在控制器里面了,並沒有做過多的分層調用,RedisKey也沒有做配置話,而是反復在用;實際項目中Redis是可以單獨做一個模塊的,架構的層級分化明確了也可以大大的提升Redis的復用性;當然這些只是建議和思路,主要還是看當前每個人手頭的架構為主。


其他組合關系型方法

至於其他的關系型的組合方法就在下面簡要做做介紹了,純手碼寫得也挺累,望大家體諒。。

  • 隊列和字符串類型

隊列和字符串類型一樣可以把數據關系型

思路:同樣的list存索引的key(ID或唯一識別ID),字符串存json字符串,字符串的key同樣后綴加唯一識別ID來進行區分。當需要輸出到頁面上的時候json_decode過來就行了

隊列和字符串的優點是存儲的空間小,劣勢在於存的時候要解析成字符串,取的時候要解析為數組或對象

  • 集合和字符串類型

集合和字符串類型一樣可以把數據關系型

思路:大家應該都知道 redis集合有有序集合和無序集合之分,在有些場景中,其實用集合的形勢反而更靈活(多維度集合控制),比如 關注我的人、我關注的人、同時互相關注的、QQ中的'可能認識的人'、異步寫入時分區間等等等...

  • 集合和哈希類型

思路其實就是和上面差不多,也就是存儲方便,消耗內存相比較而言較大。

其實我本人確實推薦博客中能來些實例,在加上一些思想引導的寫法,來給大家幫助,因為這正是我當初成長時希望看到的博客,而不是全部都是一些理論性的知識鋪天蓋地而來;希望上面所寫,能夠幫助正在工作中奮斗的你。。。

本文為作者原創,手碼不易,允許轉載,轉載后請以鏈接形式說明文章出處. 如轉載但不標明來源,后果自負。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM