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); }
打印的數據如下:
- 接下來 我們要把從數據庫取出來的數據存入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的數據(而且順序和從數據庫取出來的順序是一樣的)
第三個取出其中一個哈希查看數據
- 可以看出來 我們想要的數據已經存入了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); }
- 我們來看看打印的結果
這樣取出來的數據是不是一樣可以遍歷到模版上?
- 最后來完整的做一個例子
思路:我們的目的是從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; }
- 不管我把
redis
的key
手動刪除還是redis
的key
存在 我們輸出的都是這個(這是我的瀏覽器插件json-handle的效果)
- 刪除
redis
的key
效果依舊
那么肯定有人又要問了 你這只是在讀數據庫 如果我增 刪 改 后 redis
不同步了哇
是這樣的,所以一般我們在實際商業項目中 做一個大型的redis
數據隔離都需要把mysql
的增刪改 綁上同步的redis
操作,這樣下來,我每次讀redis
既大大的提升了性能,也保障了數據的同步性
下面拿添加
做一個實例,如何MySQL
與redis
數據同步
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 '寫入失敗'; }
- 頁面響應
- redis查看一下有沒有同步寫入
我們發現數據同步進入了redis
- index方法代碼不變 再請求一次 數據也明顯同步了
以上講的就是最基本的redis隔離技術,當然為了提現的簡單點,直接都寫在控制器里面了,並沒有做過多的分層調用,RedisKey也沒有做配置話,而是反復在用;實際項目中Redis是可以單獨做一個模塊的,架構的層級分化明確了也可以大大的提升Redis的復用性;當然這些只是建議和思路,主要還是看當前每個人手頭的架構為主。
其他組合關系型方法
至於其他的關系型的組合方法就在下面簡要做做介紹了,純手碼寫得也挺累,望大家體諒。。
- 隊列和字符串類型
隊列和字符串類型一樣可以把數據關系型
思路:同樣的list存索引的key(ID或唯一識別ID),字符串存json字符串,字符串的key同樣后綴加唯一識別ID來進行區分。當需要輸出到頁面上的時候json_decode過來就行了
隊列和字符串的優點是存儲的空間小,劣勢在於存的時候要解析成字符串,取的時候要解析為數組或對象
- 集合和字符串類型
集合和字符串類型一樣可以把數據關系型
思路:大家應該都知道 redis集合有有序集合和無序集合之分,在有些場景中,其實用集合的形勢反而更靈活(多維度集合控制),比如
關注我的人、我關注的人、同時互相關注的、QQ中的'可能認識的人'、異步寫入時分區間
等等等...
- 集合和哈希類型
思路其實就是和上面差不多,也就是存儲方便,消耗內存相比較而言較大。
其實我本人確實推薦博客中能來些實例,在加上一些思想引導的寫法,來給大家幫助,因為這正是我當初成長時希望看到的博客,而不是全部都是一些理論性的知識鋪天蓋地而來;希望上面所寫,能夠幫助正在工作中奮斗的你。。。
本文為作者原創,手碼不易,允許轉載,轉載后請以鏈接形式說明文章出處. 如轉載但不標明來源,后果自負。