zoukankan      html  css  js  c++  java
  • Laravel

    Laravel - Redis 缓存三部曲 (二) Predis -基本数据隔离

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

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

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

    思路 :利用队列里的值来做需要取数据的唯一索引,利用哈希的key的后缀名做原型数据的唯一索引

    队列和哈希的组合使用优势是,取出来可以直接使用,劣势在于内存占用相比较字符串而言要大

    • 实例:因为Redis只能存数组而我们实例为了方便直接用DB类来写的,如果是ORM可以直接返回数组的
    /**
         * Display a listing of the resource.
         *
         * @return IlluminateHttpResponse
         */
        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 IlluminateHttpResponse
         */
        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 IlluminateHttpResponse
         */
        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 IlluminateHttpResponse
         */
        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 IlluminateHttpResponse
         */
        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中的'可能认识的人'、异步写入时分区间等等等...

    • 集合和哈希类型

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

    其实我本人确实推荐博客中能来些实例,在加上一些思想引导的写法,来给大家帮助,因为这正是我当初成长时希望看到的博客,而不是全部都是一些理论性的知识铺天盖地而来;希望上面所写,能够帮助正在工作中奋斗的你。。。

    本文为作者原创,手码不易,允许转载,转载后请以链接形式说明文章出处. 如转载但不标明来源,后果自负。

  • 相关阅读:
    linux 配置nginx+php-cgi
    有个故事
    2014短学期实习报告
    快速排序
    C++之共用体
    不能言传,等于不会
    java 动态绑定
    编程的理论深度
    Java 多客户端版 2048 源码
    热河看待苦难
  • 原文地址:https://www.cnblogs.com/jhcyzxx/p/10480070.html
Copyright © 2011-2022 走看看