>  기사  >  데이터 베이스  >  Redis의 비트맵 예제 분석

Redis의 비트맵 예제 분석

王林
王林앞으로
2023-05-27 21:07:16856검색

1. BitMap이란 무엇인가요?

비트를 사용하여 요소의 값이나 상태를 나타내며 요소 자체가 키입니다. 비트맵은 8비트가 바이트를 형성할 수 있다는 것을 알고 있기 때문에 저장 공간을 크게 절약할 수 있습니다. 2^32 전력 40억 데이터에는 500M의 메모리만 필요하며 이는 8배 적은 메모리입니다

2. setbit 명령 소개

setbit key offset value
 #设置bitmapkey为20220328  uid为100的用户已签到1
setbit  20220320  100 1 
setbit  20220320  200 1
 setbit  20220321  100 1
setbit  20220321  300 1
  getbit 20220320  100  #返回1,说明这个用户已签到了
  bitcount 20220320  #获取bitmap数量

bitmap의 함정

127.0.0.1:6400> setbit bittest 100 1 #设置不存在的offset返回0
(integer) 0
127.0.0.1:6400> setbit bittest 100 1 #设置已存在的offset返回1
(integer) 1

setbit maxKey 4000000000 1 # 직접적으로 더 많은 비용이 발생합니다 600M 메모리보다

/**
     * 布隆过滤器bloom Filter
     * 1.百万分之一的概率哈希冲突,所以有存在的不一定存在,但是不存在的百分百不存在
     * 2.不能删除,删除的时候不能简单的直接置为0,可能会影响其他元素的判断,其实问题不大一般生产数据也不会删除的,都是软删除
     * 3.新增数据时候写入bloom Filter
     * 4.2^32次方40亿数据内存占用才600M,超级省内存,查找速度非常快,160M内存可以在千万级数据做到1%的误判
     * 5.bitmap根据offset去申请内存的,所以要省内存的情况要限制offset值
     */
    public function bloomAction(){
        $t1 = time();
         for($i=0;$i<99;$i++){
            $bl = new BloomFilter();
            //$str = "1https://arnaud.le-blanc.net/php-rdkafka-doc/phpdoc/book.rdkafka.html?id=".time();
            $str = "https://dasda.le-blanc.net/php-rdkafka-doc/phpdoc/book.rdkafka.html?id=".mt_rand(1,99999999);
            p($str);
             $res1 = $bl->JSHash($str);//两次哈希3s,md5哈希重复的概率是百万分之一
             p($res1);
        }
        //p($res);
        $t2 = time();
        echo $t2-$t1;
    }
    /**
     * 布隆过滤器初始化 bloom Filter 执行 php  index.php "index/demo/loadDb2bloom"
     */
    public function isExistBloomAction(){
        $redis = redisCursor();
        $email = input("email","","trim");
        $tel   = input("tel","");
         $result = false;
        $msg    = "";
        if(filter_var($email,FILTER_VALIDATE_EMAIL)){
            $key1  = "bloom_user_email";
            $offset = BloomFilter::JSHash($email);
            $result = $redis->getbit($key1,$offset);
            $msg = $email;
        }elseif($tel){
            $key2  = "bloom_user_telephone";
            $offset = BloomFilter::JSHash($tel);
            $result = $redis->getbit($key2,$offset);
            $msg = $tel;
        }
         $result?apiSuccess($msg.",已存在"):apiError($msg.",不存在");
    }
    /**
     * 布隆过滤器初始化 bloom Filter 执行 php  index.php "index/demo/loadDb2bloom"
     */
    public function loadDb2bloomAction(){
        $time1 = time();
        $redis = redisCursor();
         $key1 = "bloom_user_email";
        $key2 = "bloom_user_telephone";
         //setbit() offset 必须是数字,value必须是1或0
        //$redis->setbit($key,30,1);
        $table  = "user";
        $pkid   = "id";
        $field1 = "email";
        $field2 = "telephone";
         $maxid = Db::name($table)->max($pkid);
         $size  = 5000;
        $page  = ceil($maxid/$size);
         for($i=0;$i<$page;$i++){
            $start = $i*$size;
            $where = " $pkid between ".$start."  and ".($start+$size);
            $res = Db::name($table)->where($where)->field("$field1,$field2")->select();
             if($res){//同步到bitmap
                foreach($res as $k=>$v){
                    //布隆过滤器  1.存在的不一定存在, 2.不存在的100%不存在(原因,哈希冲突可能用100W分之一的可能重复)
                    //所以注册的时候判断不存在的,百分百可以注册,存在的可以查询一下数据库是否真的不存在
                     $value1 = BloomFilter::JSHash($v["$field1"]);
                    $value2 = BloomFilter::JSHash($v["$field2"]);
                     $redis->setbit($key1,$value1,1);//email去重
                    $redis->setbit($key2,$value2,1);//mobile去重
                }
            }
             $time2 = time();
            echo $where." 消耗时间 ".($time2-$time1).PHP_EOL;
        }
         $time3 = time();
        echo " 总消耗时间 ".($time3-$time1).PHP_EOL;
    }
errree

위 내용은 Redis의 비트맵 예제 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제