Redis 三部曲之第二部 laravel中Redis 基本的数据隔离

上一篇 Redis三部曲(一)介绍了Laravel中Predis的几种基本数据类型的使用和Redis的概念,但是就算会写了,然而缓存什么时候使用呢???

下面就结合上一篇的内容给大家说说Predis的一些组合用法,队列如何配合STRING类型或者HASH类型来组合使用,甚至把非关系变成和MySQl一样成为关系型的。

队列与哈希的组合使用 - 实现数据关系化

思路:利用队列里的值来做需要取数据的唯一索引,利用哈希的key的后缀名做原型数据的唯一索引
队列和哈希的组合使用优势是,取出来可以直接使用,劣势在于内存占用相比较字符串而言要大

  1. 实例:因为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);
     }
    

    打印的数据如下:


  2. 接下来 我们要把从数据库取出来的数据存入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);
         }
    

    我们来看看打印的结果

    这样取出来的数据是不是一样可以遍历到模版上?

  3. 最后来完整的做一个例子

    思路:我们的目的是从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 效果依旧

  4. 那么肯定有人又要问了 你这只是在读数据库 如果我增 删 改 后 redis不同步了哇

    是这样的,所以一般我们在实际商业项目中 做一个大型的redis数据隔离都需要把mysql的增删改 绑上同步的redis操作,这样下来,我每次读redis既大大的提升了性能,也保障了数据的同步性

    • 下面拿添加做一个实例,如何MySQL与redis数据同步

      1. 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 '写入失败';
             }
        

        页面响应:写入成功

        1. redis查看一下有没有同步写入

          我们发现数据同步进入了redis

        2. index方法代码不变 再请求一次 数据也明显同步了

以上讲的就是最基本的redis隔离技术,当然为了提现的简单点,直接都写在控制器里面了,并没有做过多的分层调用,RedisKey也没有做配置话,而是反复在用;实际项目中Redis是可以单独做一个模块的,架构的层级分化明确了也可以大大的提升Redis的复用性;当然这些只是建议和思路,主要还是看当前每个人手头的架构为主。


  • 其他组合关系型方法

    至于其他的关系型的组合方法就在下面简要做做介绍了,纯手码写得也挺累,望大家体谅。。

    • 队列和字符串类型

      队列和字符串类型一样可以把数据关系型

      思路:同样的list存索引的key(ID或唯一识别ID),字符串存json字符串,字符串的key同样后缀加唯一识别ID来进行区分。当需要输出到页面上的时候json_decode过来就行了

      队列和字符串的优点是存储的空间小,劣势在于存的时候要解析成字符串,取的时候要解析为数组或对象

    • 集合和字符串类型

      集合和字符串类型一样可以把数据关系型

      思路:大家应该都知道 redis集合有有序集合和无序集合之分,在有些场景中,其实用集合的形势反而更灵活(多维度集合控制),比如 关注我的人、我关注的人、同时互相关注的、QQ中的'可能认识的人'、异步写入时分区间等等等...

    • 集合和哈希类型(第三部实战将用这个)

      思路其实就是和上面差不多,也就是存储方便,消耗内存相比较而言较大。

本篇基本都是参照倡哥博客而来,因为笔者也是看着博客学会的,所以直接拿来分享给大家,若有需要欢迎转载,但是务必注明来源,否则后果自负(丢丢哥不会饶了你哦)

第三篇将会是笔者根据自己最近的实战经验,感想而来的,纯自己手码,欢迎拍砖!当然还是欢迎转载,请注明来源

博客地址:http://blog8090.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • 转自:http://bbs.redis.cn/forum.php?mod=viewthread&tid=481 p...
    木十2036阅读 771评论 0 7
  • 本篇为基础篇 前言 相信很多人都玩过新浪,新浪的首页那么多模块,那么多文章,而且每天那么多的访问量, 如果每次有人...
    GQ1994阅读 3,939评论 0 1
  • 之前我写过一篇 「如何调整情绪」,有网友提出这样的问题:“当一个人对我态度不好的时候,我的理解是,他就是对我才这样...
    贝加阅读 778评论 0 3
  • 考古灵异故事其余章节简介 第一章 戒指 我是一名考古专业的学生,一般别人听到这个专业都会觉得很好奇,...
    海猫丶阅读 441评论 3 8