1. 程式人生 > 實用技巧 >Laravel - Redis 快取篇

Laravel - Redis 快取篇


redis
一.基礎篇

    Redis的使用場景想必大家多多少少都瞭解一些了。比如新浪的首頁那麼多模組,那麼多文章,如果讀資料庫是不是壓力特別大,反應是不是特別慢?但是為什麼新浪為什麼能很快的響應頁面?其中一部分功勞就是靠的Reids的快取技術。相比較Memcached筆者還是更喜歡Redis一點。

下面簡單的分析一下,歡迎拍磚!

    Redis不僅僅支援簡單的k/v型別的資料,同時還提供list,set,hash等資料結構的儲存。

    Redis支援資料的備份,即master-slave模式的資料備份。

    Redis支援資料的持久化,可以將記憶體中的資料保持在磁碟中,重啟的時候可以再次載入進行使用。

Laravel中 使用的Redis

Redis 是一款開源且先進的鍵值對資料庫。由於它可用的鍵包含了字串、雜湊、列表、集合 和 有序集合,因此常被稱作資料結構伺服器。在使用 Redis 之前,你必須通過 Composer 安裝 predis
/predis 擴充套件包(~1.0)。 安裝predis元件 composer require "predis/predis:~1.0" 配置 應用程式的 Redis 設定都在 config/database.php 配置檔案中。在這個檔案裡,你可以看到 redis 數組裡麵包含了應用程式使用的 Redis 伺服器: 'redis' => [ 'cluster' => false, 'default' => [ 'host' => '127.0.0.1', 'port' => 6379, 'database' => 0, ]
, ], 預設的伺服器配置對於開發來說應該足夠了。然而,你也可以根據使用的環境來隨意更改陣列。只需給每個 Redis 指定名稱以及在伺服器中使用的 host 和 port 即可。 基本使用方法 STRING型別 - 寫入字串型別的redis class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response
*/ public function index() { // $key = 'STRING:TEST'; $value = 'Hello-World'; // 寫入一個字串型別的redis $info = \Redis::Set($key,$value); dd($info); return view('test'); } } 讀取相應的字串 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'STRING:TEST'; // 讀取一個字串型別的redis $info = \Redis::get($key); dd($info); return view('test'); } } 和redis語法同樣的 字串也有incr和decr等遞增、遞減... LIST型別 寫入佇列 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'LIST:TEST:R'; $names = ['PHP','HTML','CSS','JavaScript','Node','Java','Ruby','Python']; // 從右往左壓入佇列 $info = \Redis::rpush($key,$names); dd($info); return view('test'); } } 寫入佇列 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'LIST:TEST:R'; $names = ['PHP','HTML','CSS','JavaScript','Node','Java','Ruby','Python']; // 獲取佇列內容(0到-1 所有 0到0是一位 0到1是兩位) $info = \Redis::lrange($key,0,-1); dd($info); return view('test'); } } 從左往右塞入佇列 連貫方法 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'LIST:TEST:L'; $names = ['PHP','HTML','CSS','JavaScript','Node','Java','Ruby','Python']; // 從左往右存資料 \Redis::lpush($key,$names); // 取出資料 $info = \Redis::lrange($key,0,-1); dd($info); return view('test'); } } HASH型別 存資料 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'HASH:TEST'; $names = ['id'=>'99', 'name'=>'AXiBa', 'age'=>'23', 'tel'=>'13995578699', 'addtime'=>'1231231233']; // 將資料寫入hash $info = \Redis::hMset($key,$names); dd($info); return view('test'); } } 取資料(取所有) class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'HASH:TEST'; $names = ['id'=>'99', 'name'=>'AXiBa', 'age'=>'23', 'tel'=>'13995578699', 'addtime'=>'1231231233']; // 取出hash裡的資料 $info = \Redis::hGetall($key); dd($info); return view('test'); } } 取資料(取個別欄位) class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'HASH:TEST'; $names = ['id'=>'99', 'name'=>'AXiBa', 'age'=>'23', 'tel'=>'13995578699', 'addtime'=>'1231231233']; // 取出hash裡的 某一個欄位的資料 $info = \Redis::hGet($key,'name'); dd($info); return view('test'); } } // 判斷這個redis key是否存在 \Redis::exists($key); SET型別 寫入一個無序集合(資料插入無順序) class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'SET:TEST'; $value = ['a','b','c','d','e']; $info = \Redis::sadd($key,$value); $info = \Redis::smembers($key); dd($info); return view('test'); } } 求兩個集合的交集 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'SET:TEST'; $key1 = 'SET:TEST:1'; $value = ['a','b','c','d','e']; $value1 = ['a','b','c','1','2']; // 寫入另一個集合 \Redis::sadd($key1,$value1); // 交集 $info = \Redis::sinter($key,$key1); dd($info); return view('test'); } } 求兩個集合的並集 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'SET:TEST'; $key1 = 'SET:TEST:1'; $value = ['a','b','c','d','e']; $value1 = ['a','b','c','1','2']; // 並集 $info = \Redis::sunion($key,$key1); dd($info); return view('test'); } } 求兩個集合的差集 class PhotoController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // $key = 'SET:TEST'; $key1 = 'SET:TEST:1'; $value = ['a','b','c','d','e']; $value1 = ['a','b','c','1','2']; // 差集 $info = \Redis::sdiff($key,$key1); dd($info); return view('test'); } } 哪個key在前,就以哪個key的值為基準。。 二.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 新增方法 $data = [ 'guid'=> '12341234123412341234123412341234', 'email'=> '[email protected]', '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中的'可能認識的人'、非同步寫入時分割槽間等等等... 集合和雜湊型別 思路其實就是和上面差不多,也就是儲存方便,消耗記憶體相比較而言較大。 參考 redis中文官網 http://www.redis.cn/ 參考 易百教程 http://www.yiibai.com/redis/redis_environment.html

Laravel - Redis 快取篇

redis


一.基礎篇

Redis的使用場景想必大家多多少少都瞭解一些了。比如新浪的首頁那麼多模組,那麼多文章,如果讀資料庫是不是壓力特別大,反應是不是特別慢?但是為什麼新浪為什麼能很快的響應頁面?其中一部分功勞就是靠的Reids的快取技術。相比較Memcached筆者還是更喜歡Redis一點。

下面簡單的分析一下,歡迎拍磚!

  • Redis不僅僅支援簡單的k/v型別的資料,同時還提供list,set,hash等資料結構的儲存。

  • Redis支援資料的備份,即master-slave模式的資料備份。

  • Redis支援資料的持久化,可以將記憶體中的資料保持在磁碟中,重啟的時候可以再次載入進行使用。

Laravel中 使用的Redis

Redis 是一款開源且先進的鍵值對資料庫。由於它可用的鍵包含了字串、雜湊、列表、集合 和 有序集合,因此常被稱作資料結構伺服器。在使用 Redis 之前,你必須通過 Composer 安裝 predis/predis 擴充套件包(~1.0)。

安裝predis元件

composer require "predis/predis:~1.0"

配置 應用程式的 Redis 設定都在 config/database.php 配置檔案中。在這個檔案裡,你可以看到 redis 數組裡麵包含了應用程式使用的 Redis 伺服器:

  1. 'redis'=>[
  2. 'cluster'=>false,
  3. 'default'=>[
  4. 'host'=>'127.0.0.1',
  5. 'port'=>6379,
  6. 'database'=>0,
  7. ],
  8. ],

預設的伺服器配置對於開發來說應該足夠了。然而,你也可以根據使用的環境來隨意更改陣列。只需給每個 Redis 指定名稱以及在伺服器中使用的 host 和 port 即可。

基本使用方法


STRING型別 - 寫入字串型別的redis

  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='STRING:TEST';
  12. $value ='Hello-World';
  13. // 寫入一個字串型別的redis
  14. $info = \Redis::Set($key,$value);
  15. dd($info);
  16. return view('test');
  17. }
  18. }
  • 讀取相應的字串
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='STRING:TEST';
  12. // 讀取一個字串型別的redis
  13. $info = \Redis::get($key);
  14. dd($info);
  15. return view('test');
  16. }
  17. }

和redis語法同樣的 字串也有incr和decr等遞增、遞減...


LIST型別

  • 寫入佇列
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='LIST:TEST:R';
  12. $names =['PHP','HTML','CSS','JavaScript','Node','Java','Ruby','Python'];
  13. // 從右往左壓入佇列
  14. $info = \Redis::rpush($key,$names);
  15. dd($info);
  16. return view('test');
  17. }
  18. }
  • 寫入佇列
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='LIST:TEST:R';
  12. $names =['PHP','HTML','CSS','JavaScript','Node','Java','Ruby','Python'];
  13. // 獲取佇列內容(0到-1 所有 0到0是一位 0到1是兩位)
  14. $info = \Redis::lrange($key,0,-1);
  15. dd($info);
  16. return view('test');
  17. }
  18. }
  • 從左往右塞入佇列 連貫方法
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='LIST:TEST:L';
  12. $names =['PHP','HTML','CSS','JavaScript','Node','Java','Ruby','Python'];
  13. // 從左往右存資料
  14. \Redis::lpush($key,$names);
  15. // 取出資料
  16. $info = \Redis::lrange($key,0,-1);
  17. dd($info);
  18. return view('test');
  19. }
  20. }

HASH型別

  • 存資料
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='HASH:TEST';
  12. $names =['id'=>'99',
  13. 'name'=>'AXiBa',
  14. 'age'=>'23',
  15. 'tel'=>'13995578699',
  16. 'addtime'=>'1231231233'];
  17. // 將資料寫入hash
  18. $info = \Redis::hMset($key,$names);
  19. dd($info);
  20. return view('test');
  21. }
  22. }
  • 取資料(取所有)
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='HASH:TEST';
  12. $names =['id'=>'99',
  13. 'name'=>'AXiBa',
  14. 'age'=>'23',
  15. 'tel'=>'13995578699',
  16. 'addtime'=>'1231231233'];
  17. // 取出hash裡的資料
  18. $info = \Redis::hGetall($key);
  19. dd($info);
  20. return view('test');
  21. }
  22. }
  • 取資料(取個別欄位)
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='HASH:TEST';
  12. $names =['id'=>'99',
  13. 'name'=>'AXiBa',
  14. 'age'=>'23',
  15. 'tel'=>'13995578699',
  16. 'addtime'=>'1231231233'];
  17. // 取出hash裡的 某一個欄位的資料
  18. $info = \Redis::hGet($key,'name');
  19. dd($info);
  20. return view('test');
  21. }
  22. }
  1. // 判斷這個redis key是否存在
  2. \Redis::exists($key);

SET型別

  • 寫入一個無序集合(資料插入無順序)
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='SET:TEST';
  12. $value =['a','b','c','d','e'];
  13. $info = \Redis::sadd($key,$value);
  14. $info = \Redis::smembers($key);
  15. dd($info);
  16. return view('test');
  17. }
  18. }
  • 求兩個集合的交集
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='SET:TEST';
  12. $key1 ='SET:TEST:1';
  13. $value =['a','b','c','d','e'];
  14. $value1 =['a','b','c','1','2'];
  15. // 寫入另一個集合
  16. \Redis::sadd($key1,$value1);
  17. // 交集
  18. $info = \Redis::sinter($key,$key1);
  19. dd($info);
  20. return view('test');
  21. }
  22. }
  • 求兩個集合的並集
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='SET:TEST';
  12. $key1 ='SET:TEST:1';
  13. $value =['a','b','c','d','e'];
  14. $value1 =['a','b','c','1','2'];
  15. // 並集
  16. $info = \Redis::sunion($key,$key1);
  17. dd($info);
  18. return view('test');
  19. }
  20. }
  • 求兩個集合的差集
  1. classPhotoControllerextendsController
  2. {
  3. /**
  4. * Display a listing of the resource.
  5. *
  6. * @return \Illuminate\Http\Response
  7. */
  8. publicfunction index()
  9. {
  10. //
  11. $key ='SET:TEST';
  12. $key1 ='SET:TEST:1';
  13. $value =['a','b','c','d','e'];
  14. $value1 =['a','b','c','1','2'];
  15. // 差集
  16. $info = \Redis::sdiff($key,$key1);
  17. dd($info);
  18. return view('test');
  19. }
  20. }

哪個key在前,就以哪個key的值為基準。。

二.Predis -基本資料隔離

佇列如何配合STRING型別或者HASH型別來組合使用,甚至把非關係變成和MySQl一樣成為關係型的。

佇列與雜湊的組合使用 - 實現資料關係化

思路 :利用佇列裡的值來做需要取資料的唯一索引,利用雜湊的key的字尾名做原型資料的唯一索引

佇列和雜湊的組合使用優勢是,取出來可以直接使用,劣勢在於記憶體佔用相比較字串而言要大

  • 例項:因為Redis只能存陣列而我們例項為了方便直接用DB類來寫的,如果是ORM可以直接返回陣列的
  1. /**
  2. * Display a listing of the resource.
  3. *
  4. * @return \Illuminate\Http\Response
  5. */
  6. publicfunction index()
  7. {
  8. //
  9. $where =['status'=>'1'];
  10. $obj = \DB::table('data_admin_login')->where($where)->get();
  11. $array = $this->objectToArray($obj);
  12. dd($array);
  13. }
  • 接下來 我們要把從資料庫取出來的資料存入Redis,用什麼樣的方法存,用什麼樣的方法取,這些東西都得考慮好;下面例項如下:
  1. /**
  2. * Display a listing of the resource.
  3. *
  4. * @return \Illuminate\Http\Response
  5. */
  6. publicfunction index()
  7. {
  8. //
  9. $where =['status'=>'1'];
  10. $obj = \DB::table('data_admin_login')->where($where)->get();
  11. $array = $this->objectToArray($obj);
  12. // 定義Redis的key
  13. $listKey ='LIST:TEST:ADMIN';
  14. $hashKey ='HASH:TEST:ADMIN:';
  15. // 遍歷時寫入Redis list為索引 hash為資料
  16. foreach($array as $v){
  17. \Redis::rpush($listKey,$v['guid']);
  18. \Redis::hMset($hashKey.$v['guid'],$v);
  19. }
  20. return'快取寫入成功';
  21. }
  • 檢視下redis裡面的情況 第一個 檢視所有key 發現有1個佇列和16個雜湊
    第二個 取LIST:TEST:ADMIN 整個佇列 發現有16個 唯一識別ID的資料(而且順序和從資料庫取出來的順序是一樣的)

第三個取出其中一個雜湊檢視資料

  • 可以看出來 我們想要的資料已經存入了redis中,接下來,如果我想通過redis直接獲取MySQL中管理員的列表資料怎麼使用呢?
  1. /**
  2. * Display a listing of the resource.
  3. *
  4. * @return \Illuminate\Http\Response
  5. */
  6. publicfunction index()
  7. {
  8. //
  9. // 定義Redis的key
  10. $listKey ='LIST:TEST:ADMIN';
  11. $hashKey ='HASH:TEST:ADMIN:';
  12. // 取出admin佇列的唯一識別id陣列
  13. $list = \Redis::lrange($listKey,0,-1);
  14. $array =null;
  15. foreach($list as $v){
  16. // 取出雜湊裡的資料寫入大陣列中
  17. $array[]= \Redis::hGetall($hashKey.$v);
  18. }
  19. dd($array);
  20. }

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

  • 最後來完整的做一個例子
    思路:我們的目的是從redis裡面取出想要輸出到模版上的資料,但是redis大家也知道,只是快取伺服器重啟了,就沒了(除非做磁碟持久化),但是我要做的是如果Redis裡面沒有我要從MySQL裡面取,取到了然後寫入Redis,保證對MySQL的請求大大減少。
  1. /**
  2. * Display a listing of the resource.
  3. *
  4. * @return \Illuminate\Http\Response
  5. */
  6. publicfunction index()
  7. {
  8. //
  9. // 定義Redis的key
  10. $listKey ='LIST:TEST:ADMIN';
  11. $hashKey ='HASH:TEST:ADMIN:';
  12. // 檢視key是否存在?
  13. if(empty(\Redis::exists($listKey))){
  14. // 如果Redis不存在 讀資料庫然後寫入redis
  15. $where =['status'=>'1'];
  16. $obj = \DB::table('data_admin_login')->where($where)->get();
  17. $array = $this->objectToArray($obj);
  18. // 遍歷時寫入Redis list為索引 hash為資料
  19. foreach($array as $v){
  20. \Redis::rpush($listKey,$v['guid']);
  21. \Redis::hMset($hashKey.$v['guid'],$v);
  22. }
  23. return $array;
  24. }
  25. // 如果redis存在 直接讀redis的資料
  26. // 取出admin佇列的唯一識別id陣列
  27. $list = \Redis::lrange($listKey,0,-1);
  28. $array =null;
  29. foreach($list as $v){
  30. $array[]= \Redis::hGetall($hashKey.$v);
  31. }
  32. return $array;
  33. }
  34. ```
  35. * 不管我把redis的key手動刪除還是redis的key存在 我們輸出的都是這個(這是我的瀏覽器外掛json-handle的效果)
  36. * 刪除redis的key 效果依舊
  37. 那麼肯定有人又要問了 你這只是在讀資料庫 如果我增 刪 改 後 redis不同步了哇
  38. 是這樣的,所以一般我們在實際商業專案中 做一個大型的redis資料隔離都需要把mysql的增刪改 綁上同步的redis操作,這樣下來,我每次讀redis既大大的提升了效能,也保障了資料的同步性
  39. 下面拿新增做一個例項,如何MySQL與redis資料同步
  40. restfulApi 新增方法
    $data = [
            'guid'=> '12341234123412341234123412341234',
            'email'=> '[email protected]',
            '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中的'可能認識的人'、非同步寫入時分割槽間等等等...

  • 集合和雜湊型別
    思路其實就是和上面差不多,也就是儲存方便,消耗記憶體相比較而言較大。

參考 redis中文官網 http://www.redis.cn/
參考 易百教程 http://www.yiibai.com/redis/redis_environment.html