前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >workerman实现redis bit位图实现用户签到PHP实例

workerman实现redis bit位图实现用户签到PHP实例

作者头像
用户8262580
发布2022-06-08 04:45:41
5360
发布2022-06-08 04:45:41
举报
文章被收录于专栏:Linux初学者Linux初学者

本文环境 CentOS8.0,PHP8.1,Nginx1.8,Workerman 4.0\ 不懂的可以评论或联系我邮箱:owen@owenzhang.com\ 著作权归OwenZhang所有。商业转载请联系OwenZhang获得授权,非商业转载请注明出处。

image.png

workerman介绍

Workerman是一款纯PHP开发的开源高性能的PHP 应用容器

Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的服务框架,你可以用它开发tcp代理、做游戏服务器、邮件服务器、ftp服务器、甚至开发一个php版本的redis、php版本的数据库、php版本的nginx、php版本的php-fpm等等。Workerman可以说是PHP领域的一次创新,让开发者彻底摆脱了PHP只能做WEB的束缚。

实际上Workerman类似一个PHP版本的nginx,核心也是多进程+Epoll+非阻塞IO。Workerman每个进程能维持上万并发连接。由于本身常驻内存,不依赖Apache、nginx、php-fpm这些容器,拥有超高的性能。同时支持TCP、UDP、UNIXSOCKET,支持长连接,支持Websocket、HTTP、WSS、HTTPS等通讯协议以及各种自定义协议。拥有定时器、异步socket客户端、异步Redis、异步Http、异步消息队列等众多高性能组件。

Redis bitmap位图介绍

在平时开发过程中,经常会有一些 bool 类型数据需要存取。比如记录用户一年内签到的次数,签了是 1,没签是 0。如果使用 key-value 来存储,那么每个用户都要记录 365 次,当用户成百上亿时,需要的存储空间将非常巨大。为了解决这个问题,Redis 提供了位图结构。

位图(bitmap)同样属于 string 数据类型。Redis 中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个字节又由 8 个 Bit 位组成。位图结构正是使用“位”来实现存储的,它通过将比特位设置为 0 或 1来达到数据存取的目的,这大大增加了 value 存储数量,它存储上限为2^32 。

php 实例

代码语言:javascript
复制
//setBit($key, $offset, $value)
        //$offset参数需要大于等于0,并且小于 2^32 = 4294967296 (bitmaps 最大 512MB)
        //$value 偏移量上的位 0和1
        //不建议用下面方法,这样造成0到20220101值为空 数据量太大
        // 可以key上面显示年份或者月份,然后day1-365这样 key大小就比较合理
        $data = [
            [
                'day'     => 20220101,//日期 2022年1月1号
                'sign_in' => 1,//签到 1有 0无
            ],
            [
                'day'     => 20220102,
                'sign_in' => 0,
            ],
            [
                'day'     => 20220322,
                'sign_in' => 1,
            ],
        ];
        //1-1231不存在的值都设置为0
        $data = [
            [
                'day'     => 101,//日期 1月1号
                'sign_in' => 1,//签到 1有 0无
            ],
            [
                'day'     => 211,
                'sign_in' => 0,
            ],
            [
                'day'     => 1102,
                'sign_in' => 1,
            ],
            [
                'day'     => 1231,
                'sign_in' => 1,
            ],
        ];
//        foreach ($data as $datum) {
//            //写入用户10026的签到位图
//            Redis::setBit('bitSingIn:userId:10026', $datum['day'], $datum['sign_in']);
//        }

        $day = $request->post('day');
        //获取用户10026的某天签到情况
        $sign_in = Redis::getBit('bitSingIn:userId:10026', $day);
        //统计用户的签到次数
        $bitCount = Redis::bitCount('bitSingIn:userId:10026');
        //获取首次签到的日期
        $bitCount = Redis::bitPos('bitSingIn:userId:10026', 1);

        return $this->apiSuccess(compact('day', 'sign_in', 'bitCount'));

复制

redis bit位图命令

代码语言:javascript
复制
# 用户2月17号签到
SETBIT u:sign:1000:201902 16 1 # 偏移量是从0开始,所以要把17减1

# 检查2月17号是否签到
GETBIT u:sign:1000:201902 16 # 偏移量是从0开始,所以要把17减1

# 统计2月份的签到次数
BITCOUNT u:sign:1000:201902

# 获取2月份前28天的签到数据
BITFIELD u:sign:1000:201902 get u28 0

# 获取2月份首次签到的日期
BITPOS u:sign:1000:201902 1 # 返回的首次签到的偏移量,加上1即为当月的某一天

复制

场景需求

适用场景如签到送积分、签到领取奖励等,大致需求如下:

签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等。

如果连续签到中断,则重置计数,每月初重置计数。

当月签到满3天领取奖励1,满5天领取奖励2,满7天领取奖励3……等等。

显示用户某个月的签到次数和首次签到时间。

在日历控件上展示用户每月签到情况,可以切换年月显示……等等。

运行结果和redis key存储情况

redis服务

代码语言:javascript
复制
<?php
/**
 * This file is part of webman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author    walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link      http://www.workerman.net/
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */

namespace support;

use Illuminate\Redis\RedisManager;
use Workerman\Timer;

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • workerman介绍
  • Redis bitmap位图介绍
  • php 实例
  • redis bit位图命令
  • 场景需求
  • 运行结果和redis key存储情况
  • redis服务
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档