开发者社区> 亦征> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

201604深圳云栖大会Workshop - 使用表格存储开发用户弹幕功能

简介: 使用表格存储开发用户弹幕功能 目标 使用表格存储(TableStore,原称OTS)实现视频直播的弹幕功能,通过TableStore存储弹幕,并在TableStore中检索最新弹幕实时显示到直播页面中。
+关注继续查看

使用表格存储开发用户弹幕功能

目标

  • 使用表格存储(TableStore,原称OTS)实现视频直播的弹幕功能,通过TableStore存储弹幕,并在TableStore中检索最新弹幕实时显示到直播页面中。

准备工作

  • TableStore主页和控制台等

TableStore主页

TableStore控制台

AccessKey获取页面

TableStore文档和SDK

阿里云Code

  • 注意事项:预计耗费的费用

TableStore是一个按量计费的服务,根据存储量、读写吞吐量、外网流量等付费。具体的价格通过TableStore价格总览这个页面来获取。

TableStore目前每月赠送免费额度,包含1000万按量读、1000万按量写以及10GB存储。

考虑到TableStore的免费额度,在搭建视频网站过程中,除外网下行流量的费用外,将不会产生其他相关费用,因此课程中产生的总费用极低。

步骤

1. 创建TableStore实例。

打开TableStore控制台。点击右上角创建实例。

screenshot

创建完成后可以看到我们刚刚创建的实例。

screenshot

点击实例,可以进入实例详情页。

ots_3

在实例详情页,我们可以查看该实例的访问地址,公网访问地址用于从公网访问,会收取外网下行流量费用,私网访问地址用于在阿里云的ECS上访问,通过阿里云内网线路,不收取流量费用。

TableStore提供RESTful API接口,用户通过TableStore提供的各语言SDK进行数据操作以及表操作,在使用SDK时需要指定实例访问地址、AccessKeyId、AccessKeySecret、实例名。

2. 创建数据表。

在实例详情页,我们可以创建数据表(通过SDK也可以建表),如下图所示。

ots_4

我们创建了名为danmaku的一张表,用于存储弹幕。预留的读写吞吐量全部设置为0,即不预留,完全采用按量计费的模式(预留会按照预留吞吐量计费)。

创建数据表时,设置表的主键非常重要。TableStore中的一行由主键列和属性列构成,主键列最多可以有4列,他们按照顺序构成一个主键,主键唯一的决定一行,不会有重复,TableStore会按照主键的大小对行进行排序。属性列目前最多可以有1024列,每行的属性列列数和列名都可以不同,而每行的主键列的列数和列名都是相同的。因此TableStore是半结构化类型的数据库。

这里我们设置三列主键分别为VideoID,Timestamp,UserID,分别代表视频的ID,弹幕发送时的服务端时间,弹幕发送者的ID。由于TableStore会按照主键排序,因此同一个VideoID下,Timestamp是有序的,可以使用TableStore的范围读取功能从某个Timestamp开始获取更新的弹幕。

加入UserID作为第三列主键,可以保证主键的唯一性。我们使用毫秒单位的Timestamp,假如同一视频在同一毫秒有两条弹幕写入,这两条弹幕的主键会重复,其中一条会覆盖另一条。有很多方法可以保证主键的唯一性,我们采用的是加入UserID作为第三列主键的方式。

弹幕的内容我们保存在属性列中,属性列还可以保存很多其他信息。TableStore是半结构化类型的数据库,因此可以动态的增加属性列,非常灵活。

3. 使用TableStore PHP SDK进行数据读写。

  • 整个过程如下图所示,网页端在发送或获取弹幕时先访问php服务端,由php服务端调用TableStore的php sdk进行数据读写。

screenshot

我们使用了两个接口,PutRow和GetRange,结合我们建表时设计的主键,数据读写的示意图如下:

screenshot

写入一条弹幕:VideoID、UserID、Text由网页端提供,Timestamp使用服务端当前时间,调用PutRow接口写入。

获取最新弹幕:网页端提供VideoID,并提供一个startTimestamp,表示从该Timestamp开始读取,调用GetRange接口,设置起始主键为(VideoID, startTimestamp, ""),结束主键为(VideoID,服务端当前时间,"")。

好,下面进入具体的代码部分,我们在阿里云Code上查看代码,我们需要打开“demo/DanmakuDataModel.class.php”这个文件。

  • 准备配置,包含endpoint(实例访问地址)、instanceName(实例名)、AccessKeyId和AccessKeySecret。

screenshot

在上图中的位置设置相关配置。

  • 根据配置构造otsClient,通过otsClient调用OTS的API。

代码如下:

public static function init() {
     self::$otsClient = new OTSClient(array(
                    'EndPoint' => OTS_END_POINT,
                    'AccessKeyID' => OTS_ACCESS_KEY_ID,
                    'AccessKeySecret' => OTS_ACCESS_KEY_SECRET,
                    'InstanceName' => OTS_INSTANCE_NAME
                 )); 
} 
  • 将弹幕写入TableStore

我们通过TableStore的PutRow接口,将一条弹幕写入TableStore的数据表中。

在使用PutRow接口前,强烈建议用户阅读我们的API参考手册

上面我们建表时设置的主键列分别为VideoID、Timestamp、UserID,我们设置对应的主键值构造出"primary_key", 然后将其他的一些信息存在属性列中,即构造attribute_columns。

代码如下所示:

public static function put($danmaku) {
    $request = array(
            'table_name' => self::$tableName,
            'condition' => 'IGNORE',
            'primary_key' => array(
                self::$pk1 => $danmaku["VideoID"],
                self::$pk2 => $danmaku["Timestamp"],
                self::$pk3 => $danmaku["UserID"]
                ),
            'attribute_columns' => array(
                'text' => $danmaku["text"]
                )
            );
    $response = self::$otsClient->putRow($request);
    return true;
}

注意到$request中还有一个参数为condition,这个是设置行的存在性条件,我们在此设置为IGNORE,即不关心该行在写入前是否存在。

  • 通过TableStore读取弹幕

读取弹幕时我们使用TableStore的GetRange接口,该接口设置一个起始主键和一个结束主键,读取该范围内的行。

同样,我们首先阅读API参考手册,对GetRange接口有一个了解。

前端的视频页面保存最后一条弹幕的Timestamp,获取弹幕时将该时间戳传给PHP端,希望获取该时间戳后的最新弹幕。PHP端根据该时间戳构造起始主键,根据当前时间构造结束主键,然后调用GetRange接口进行查找。

由于起始主键和结束主键中的数据可能非常多,一次GetRange调用可能无法取得全部数据,当遇到这种情况,GetRange会返回next_start_primary_key,表示要扫描的下一个主键的值,可以将这个next_start_primary_key设置为起始主键进行下一次查询。

代码如下:

public static function get($conditions) {
    $startPk = array(
            self::$pk1 => $conditions["VideoID"],
            self::$pk2 => $conditions["StartTime"],
            self::$pk3 => ""
            );
    $endPk = array(
            self::$pk1 => $conditions["VideoID"],
            self::$pk2 => (int)(microtime(true) * 1000),
            self::$pk3 => ""
            );

    $request = array(
            'table_name' => self::$tableName,
            'direction' => 'FORWARD',
            'inclusive_start_primary_key' => $startPk,
            'exclusive_end_primary_key' => $endPk,
            'limit' => self::$getRangeLimit
            );

    $list = array();
    while (true) {
        $response = self::$otsClient->getRange($request);
        foreach ($response["rows"] as $item) {
            $list[] = array(
                    'VideoID' => $item["primary_key_columns"]["VideoID"],
                    'Timestamp' => $item["primary_key_columns"]["Timestamp"],
                    'UserID' => $item["primary_key_columns"]["UserID"],
                    'text' => $item["attribute_columns"]["text"]
                    );
        }
        if (count($list) >= self::$getDanmakuLimit) {
            break;
        }
        if ($response["next_start_primary_key"] == NULL) {
            break;
        } else {
            $requset["inclusive_start_primary_key"] = $response["next_start_primary_key"];
        }
    }
    return $list;
}

4.与前端视频页面进行交互。

  • 弹幕效果:

screenshot

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
7 Papers & Radios | OpenAI教GPT-3学会上网;爱因斯坦广义相对论通过严格检验
7 Papers & Radios | OpenAI教GPT-3学会上网;爱因斯坦广义相对论通过严格检验
50 0
k8s使用ceph实现动态持久化存储
简介 本文章介绍如何使用ceph为k8s提供动态申请pv的功能。ceph提供底层存储功能,cephfs方式支持k8s的pv的3种访问模式ReadWriteOnce,ReadOnlyMany ,ReadWriteMany ,RBD支持ReadWriteOnce,ReadOnlyMany两种模式 访问模式只是能力描述,并不是强制执行的,对于没有按pvc声明的方式使用pv,存储提供者应该负责访问时的运行错误。
3068 0
内存数据库内核开发 工作日志(内存索引实现原理)(附红黑树实现清晰完整直接可编译运行代码)(十)
  这里回到文章主目录 [置顶]内存数据库内核开发探索        之前由于考虑到使用Page的内存和磁盘互换的机制实现了B-tree做为数据库的键值索引,在真实的生产环境下2000万以上的数据建立索引会使到B-tree层数增多,效率明显下降,在运算工程中使用AIX大型机都用了数天才将2000多万的数据生成出来,效果非常不理想。
793 0
[LeetCode] Design Log Storage System 设计日志存储系统
You are given several logs that each log contains a unique id and timestamp. Timestamp is a string that has the following format: Year:Month:Day:Hour:Minute:Second, for example, 2017:01:01:23:59:59.
1490 0
表格存储(TableStore)新功能Stream应用场景介绍
上面一篇我们介绍了表格存储新功能Stream, 下面我们展开说一些场景,看看有了Stream后,哪些我们常见的应用场景可以更高效的设计和实现。 直播用户行为分析和存储 场景描述 现在视频直播非常火热,假如我们使用TableStore记录用户的每一次进入房间和离开房间,房间内的操作记录等,并希望根据用户的最近的观看记录,更新直播推荐列表。
5834 0
对于连接后,需要打开浏览器输入用户名密码才能上网的WIFI,不跳转的解决方法
对于连接后,需要打开浏览器输入用户名密码才能上网的WIFI,如果你打开浏览器后,访问一个网址,会自动显示一个要求你输入用户名密码的网页,但是我遇到的情况是访问之前经常访问的网址,怎么刷新都打不开网页,原因是因为我访问的都是之前经常访问的网址,域名的DNS已经缓存,当我访问一个从来都没有访问过的网址时,就自动跳转到要求输入用户名和密码的页面了。
872 0
201601上海云栖大会Workshop - 通过日志服务采集、分析日志
通过日志服务采集、分析日志 (ETA: 20 分钟) 目标 掌握阿里云日志服务基本功能 成功收集Docker中日志,利用EMR(Spark Streaming,Hive)进行日志分析 准备工作 产品基本介绍(链接) 注意事项: 日志服务当前免费使用,无耗费 Docker运行集群会产
3467 0
syslog远程日志存储
A机和B机,A机做日志数据存储服务器,B机是syslog日志产生。两个主机的/etc/syslog.
540 0
存储过程介绍及asp存储过程的使用
一、先介绍一下什么是存储过程 存储过程是利用SQL Server所提供的Tranact-SQL语言所编写的程序。Tranact-SQL语言是SQL Server提供专为设计数据库应用程序的语言,它是应用程序和SQL Server数据库间的主要程序式设计界面。
694 0
+关注
亦征
阿里云数据库表格存储(TableStore) 高级开发工程师
文章
问答
文章排行榜
最热
最新
相关电子书
更多
效率提升:表格存储实时数据流:Stream的技术揭秘和应用场景
立即下载
ECS云磁盘热迁移
立即下载
IFAA为身份认证保驾护航
立即下载