• 写一些脚本的心得总结系列第4篇-------从数据库同步到redis


    5.从数据库同步到redis的。

    redis把数据放内存里,读取都非常方便,也提供了远超memcache的丰富数据结构。
    下面我举2个例子,比如
    1)把数据从数据库写入到redis:

    <?php
    
    $redis = MyRedis::getInstance();
    $tables = ['users', 'games', 'tasks'];
    foreach ($tables as $table)
    {
        //echo '$i=' . $i,',$table=' . $table, "<br>";
        $sql = "select * from $table;";
        $datas = $mysql->select($sql);
    
        foreach ($datas as $data)
        {
            //往redis中写数据。
            if ($table == 'users')
            {
                $redis->hSet('mycloud_' . $table, $data['user_name'], json_encode($data));
            }
    
            else {
                $redis->hSet('mycloud_' . $table, $data['user_id'], json_encode($data));
            }
    
        }
    }

    Redis hash是一个string类型的field和value的映射表.它的添加、删除操作都是O(1)(平均)。
    hash特别适合用于存储对象。相较于将对象的每个字段存成单个string类型。将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。省内存的原因是新建一个hash对象时开始是用zipmap(又称为small hash)来存储的。这个zipmap其实并不是hash table,但是zipmap相比正常的hash实现可以节省不少hash本身需要的一些元数据存储开销。尽管zipmap的添加,删除,查找都是O(n),但是由于一般对象的field数量都不太多。所以使用zipmap也是很快的,也就是说添加删除平均还是O(1)。如果field或者value的大小超出一定限制后,Redis会在内部自动将zipmap替换成正常的hash实现. 这个限制可以在配置文件中指定
      hash-max-zipmap-entries 64 #配置字段最多64个。
      hash-max-zipmap-value 512 #配置value最大为512字节。
      hset 设置hash field为指定值,如果key不存在,则先创建。Set结构会自动去重,且hset非常节省空间,所以整表数据写入redis可以用这个操作。
    它的读取也很简单:
    // 根据某用户名获取该用户记录信息
    $redis = PHPRedis::getInstance(); //连接Redis数据库
    $user = json_decode($redis->hget('mycloud_users', $userName), true);
    return $user ? $user : array();

    其中,json_decode第二个参数传true,将返回 array 而非 object 。

    当然hSet的时候不一定非要用json_encode,也可以使用serialize。redis最重要的是要找到唯一key去对应存储数据。

    2)登录日志同步到数据库
    可以利用redis中的list操作来实现。

    封装的redis 操作如下:

    public function lPush($key, $data) {
        if ($this->conn) {
            return $this->_redis->lPush($key, json_encode($data));
        }
    }
    
    /**
     * 从队列右边取出一条记录
     * @param string $key 队列名称
     * @param bool $isBlock true-以阻塞方式读取;false-非阻塞方式读取
     */
    public function rPop($key, $isBlock = true) {
        if ($this->conn) {
            if ($isBlock) {
                $result = $this->_redis->brPop($key);
            } else {
                $result = $this->_redis->rPop($key);
            }
    
            return json_decode($result, true);
        }
    
        return array();
    }



    任务队列一般适用于生产者和消费者之间通信的,那么在redis中很容易想到使用列表类型来实现任务队列,具体方法是创建一个任务队列,生产者主动lpush数据,而消费者去rpop数据,保持一个先进先出的循序。
    但是这样存在一个问题,消费者需要主动去请求数据,周期性的请求会造成资源的浪费,因此,redis提供了一个brpop的命令来解决这个问题。
    BRPOP key timeout
    brpop命令接收两个参数,第一个参数key为键值,第二个参数timeout为超时时间。BRPOP命令取数据时候,如果暂时不存在数据,该命令会一直阻塞直到达到超时时间。如果timeout设置为0,那么就会无限等待下去。

    这里默认是用了brPop方式,阻塞方式读取。

    生产者相关调用代码:
    <?php
    // 登录相关代码....
    $myRedis->lPush('users_login_log', $logData);


    消费者的调用:

    $listLog = $myRedis->rPop('usrs_login_log');
    $row = json_decode($listLog, true);
    // 后面再入库......

    再聊就都是Redis实践的干货了,还是以后单开一篇博客来总结吧。

  • 相关阅读:
    89、Beego框架(上)——2020年07月30日22:05:40
    88、go框架有哪些-转载——2020年07月30日12:56:43
    86、go语言优势-转载——2020年07月27日16:08:04
    85、go开发配置环境——2020年07月27日13:08:27
    84、Linux命令——2020年07月27日12:51:44
    83、Linux知识-系统介绍、文件系统、远程操作——2020年07月27日12:47:14
    82、《给年轻人的极简金融课》-童哲——2020年7月23日20:17:49
    81、nodejs学习——2020年07月22日13:30:25
    无法启动此程序,因为计算机中丢失VCRUNTIME140.dll 尝试重新安装此程序以解决此问题
    关于js单页面实现跳转原理以及利用angularjs框架路由实现单页面跳转
  • 原文地址:https://www.cnblogs.com/freephp/p/5094658.html
Copyright © 2020-2023  润新知