点击上方“蓝字”关注我们

菜菜哥,紧急求助呀

怎么回事?产品经理砍你了?

没有,只是写了个新项目,上线就被压垮了

什么功能,这么强悍?

一个记录用户观看视频进度信息的功能

那如果用户基数大,确实是需要注意的,那我给你分析一下哈

背景

每一个片子的幕后,都保留了你的观看记录,详细的记着你观看了几次,跳过了那些时长 ,据说根据这些数据可以分析出你喜欢哪个日本明星,以此来做定向推送......

虽然看起来很简单的一个功能,其实涉及到的数据量非常大,极限情况下为你的用户数*视频数的乘积。

那么在只有两个网站服务器,一台sqlserver的情况下,该如何面对这样不算大数据量的写请求呢?为什么说是写请求呢?因为用户观看视频的每一秒你都需要记录下来,例如:视频的第十秒用户观看了。要想把这个功能搞定,首先需要定义几个事情:

1. 记录用户观看视频情况的数据定义

2. 和客户端交互的数据协议

3. 数据库中记录的数据格式

4. 如何解决服务器写的压力(毕竟单台服务器请求数还是比较大)

解决方案

用户观看视频进度定义

对于一个视频来说,假如有1个小时的时长,这3600秒对应着3600个是否已经观看的状态,对于观看状态来说,只有观看和未观看两种状态,所以一个bit足以,一个字节(byte)有8个bit,所以一个byte可以表示8秒的观看状态,以此为基础,进制越高,同样数量的字符表示的状态就越多。

客户端每次上传新的数据,需要和服务端已经存在的数据做位运算,例如:01000  表示第二秒观看了 ,客户端新上传:00011 表示第4,5秒都观看了,对于用户而言这个视频第2,4,5 秒都看过,虽然只是一个简单的运算,但是量大的时候,对cpu的消耗不容小觑。

第一字节    第二字节0 1 2 3 4 5 6 7  0 1 2 3 4 5 6 7
bit:  1 0 0 0 1 0 0 0  0 1 0 0 0 0 0 0
二进制:  0x88    0x40
字符串:  8840

和客户端交互协议

用户观看视频的进度实时信息,只有客户端知道,客户端需要上传用户的观看进度数据,和服务端交互的进制可以选择通用性比较强的16进制,当然你选择100进制也无所谓,只要双方能同时支持,并且能正常解析即可

数据库数据格式

每种数据库支持的数据类型有差异,所以这里不在过多叙述,当然无论什么格式,占用空间越少越好,但也要根据业务的计算量来综合考虑。

解决问题

cpu性能问题

毕竟要把用户每次最新的观看数据和老数据做合并工作,在用户量大的情况下不容小觑。在综合了各种条件之后,最终采用10进制来做合并工作,客户端上传上来16进制数据,然后转化为十进制,然后和观看记录(10进制)做合并运算,这部分cpu省略不了,具体转化程序为:

//需要新加的数据ConcurrentQueue<UserVideoInfo> AddQueue = new ConcurrentQueue<UserVideoInfo>();//把16进制的字符串按照两位 分割成十进制数组protected List<int> ConvertToProgressArray(string progressString){if (string.IsNullOrWhiteSpace(progressString)){return null;}//验证是否为2的倍数长度if (progressString.Length % 2 != 0){return null;}var proStrSpan = progressString.AsSpan();List<int> ret = new List<int>();int i = 0;while (i < proStrSpan.Length){ret.Add(int.Parse(proStrSpan.Slice(i, 2).ToString(), System.Globalization.NumberStyles.HexNumber)); ;i = i + 2;}return ret;}

客户端请求数量问题

如果同时一万用户在同时观看视频,上传数据时间间隔为2秒,意味着每秒有5000请求。由于这个业务只是一个用户log型业务,何为log型,就是说可以容忍一部分数据丢失,针对这个数据形态,客户端可以先在本地做缓冲记录,没有必要一秒上传一次记录,例如现在约定的客户端30秒上传一次记录,如果用户关掉客户端,下次启动的时候会重新上传未成功的记录。

数据库压力

如果每次请求都单独更新数据库,按照第二条的计算每秒高达5000次update请求。用户观看每次视频都加载内存中缓存,仔细分析这种业务,由于是log型数据,所以每次你请求没有必要都去更新数据库,而是先更新了缓存,然后定时去更新数据库。

由于数据量的问题,所有的更新操作都会发送到一个任务队列,队列的执行者会根据配置批量更新数据库,这样比单条更新数据库性能要高很多,其实这种方案在很多log型的业务中都有使用,批量更新对数据库的压力要小很多,代码类似以下

public async Task<int> AddUserVideoData(UserVideoInfo data, DBProcessEnum processType = DBProcessEnum.Update){if(processType== DBProcessEnum.Add){AddQueue.Enqueue(data);}return 1;}void MulProcessData(){//每次更新的条数int maxNumber = 50;List<UserVideoInfo> data = new List<UserVideoInfo>();while (true){if (data == null){data = new List<UserVideoInfo>();}try{                   if (!AddQueue.Any() && !UpdateQueue.Any()){System.Threading.Thread.Sleep(500);}                   else{//先处理 需要更新的data.Clear();while (data.Count <= maxNumber && AddQueue.Any()){if (!AddQueue.TryDequeue(out UserVideoInfo value)){                                continue;}//判断是否有重复对象if (data.Any(s => s.UserId == value.UserId && s.VideoId == value.VideoId)){var exsitItem = data.First(s => s.UserId == value.UserId && s.VideoId == value.VideoId);exsitItem = value;}else{data.Add(value);}}if (data != null && data.Any()){var ret = UserVideoProgressProxy.Add(data);}}}catch (Exception err){}}}

写在最后

其实这种高IO的操作用sqlserver这种关系型数据库反而不好,Nosql在这种简单高IO的情境下要很多,改天可以改为redis试一试,估计会比sqlserver要好很多。

●程序员修神之路--为什么我会了SOA,你们还要逼我学微服务?

●程序员过关斩将--数据库的乐观锁和悲观锁并非真实的锁

●程序员修神之路--设计一套RPC框架并非易事

●程序员过关斩将--要想获取我的用户信息,就得按照规矩来

●程序员过关斩将--更加优雅的Token认证方式JWT

●程序员过关斩将--cookie和session的关系其实很简单

●程序员修神之路--用NOSql给高并发系统加速

●程序员修神之路--高并发系统设计负载均衡架构

●程序员过关斩将--你为什么还在用存储过程?

●程序员修神之路--问世间异步为何物?

●程序员修神之路--提高网站的吞吐

长按添加菜菜好友

关注后回复:“大礼包”和“福利”,领取惊喜

点亮在看,你最好看!

程序员过关斩将--从每秒6000写请求谈起相关推荐

  1. 程序员过关斩将--应对高并发系统有没有通用的解决方案呢?

    " 灵魂拷问: 应对高并发系统有没有一些通用的解决方案呢? 这些方案解决了什么问题呢? 这些方案有那些优势和劣势呢? 对性能孜孜不倦的追求是互联网技术不断发展的根本驱动力,从最初的大型机到现 ...

  2. 程序员过关斩将--为微服务撸一个简约而不简单的配置中心

    点击上方蓝字  关注我们 毫不犹豫的说,现代高速发展的互联网造就了一批又一批的网络红人,这一批批网红又极大的催生了特定平台的一大波流量,但是留给了程序员却是一地鸡毛,无论是运维还是开发,每天都会担心服 ...

  3. 程序员过关斩将--redis做消息队列,香吗?

    菜菜哥,我刚做完了一个订单系统,感觉很简单呀 说说看,大量的订单状态怎么处理的? 我设计的时候可是考虑了这一点,所以用了异步处理,采用了MQ 那用的什么MQ呢,透露一下呗 我用的redis做的MQ,很 ...

  4. 程序员过关斩将--自定义线程池来实现文档转码

    背景 我司在很久之前,一位很久之前的同事写过一个文档转图片的服务,具体业务如下: 1. 用户在客户端上传文档,可以是ppt,word,pdf 等格式,用户上传完成可以在客户端预览上传的文档,预览的时候 ...

  5. 程序员过关斩将--少年派登录安全的奇幻遐想

    " 据说,这篇也是快餐,完全符合年轻人口味 说到登录,无人不知无人不晓.每一个有用户体系的相关系统都会有登录的入口,登录是为了确认操作人的正确性.说到登录安全,其实是一个很伟大的命题,不过常 ...

  6. 程序员过关斩将--请不要误会redis 6.0 的多线程

    " 你对redis的单线程是不是有点误会? " 你对redis 6.0的多线程是不是也有点误会? " redis多线程一定可以提高性能吗? redis官方刚刚发布的6.0 ...

  7. 程序员过关斩将--解决分布式session问题

    微信搜一搜 架构师修行之路 session 说到 session,我相信每个程序员都不陌生,或多或少在项目中使用过.session 这个词,其实是一个抽象的概念,它不像 Cookie 那样有着明确的定 ...

  8. 程序员过关斩将--Http请求中如何保持状态?

    微信搜一搜 架构师修行之路 这是一个被无数程序员撸过的问题,却只有少数人了解了真相.大体上搜了一下,网上关于http协议保持状态误导大家的文章还是有的,比如:有人说利用ViewState,那是asp. ...

  9. 程序员过关斩将--作为一个架构师,我是不是应该有很多职责?

    点击上方"蓝字"关注我们领取架构书籍 每一个程序员都有一个架构梦. 上面其实本质上是一句富有事实哲理的废话,要不然也不会有这么多人关注你的公众号.这些年随着"企业数字化& ...

最新文章

  1. 针对Web应用的【攻击模式篇】
  2. 二叉树c语言程序插入某个成员,关于C ++:二叉树:插入节点算法
  3. springCloud学习-高可用的分布式配置中心(Spring Cloud Config)
  4. 【python】关于python的链表结构实现
  5. java实现星级评分功能_JavaScript实现星级评分
  6. Long Path CodeForces - 407B(动态规划+思维+公式推导)
  7. mikechen谈技术人成长的三大原则
  8. XnView v1.93.6 Final 注册机
  9. 08-图8 How Long Does It Take
  10. Linux系统定时任务Crond
  11. mysql 常用字段类型_mysql 常用字段类型
  12. html页面根据ip地址跳转页面,一、请编写一个Servlet类,实现当前页面3秒后跳转到其它页面(跳转页面自定)的功能。...
  13. word转PDF时,英文单词的字母间距问题
  14. 【Scratch一级真题解析】电子学会等级考试一级(选择题)-2021年9月
  15. #windowsxpsp3系统MS10-046漏洞测试
  16. WIN10+VS2015部署PanddleOCR
  17. 如何从AD中彻底删除Skype For Business(下篇)
  18. 前后端处理实时刷新refresh_token的使用
  19. 数独的随机终盘生成函数设计
  20. 超级解霸害死人——安装evc过程种出现“没有文件扩展.vbs的脚本引擎”的问题...

热门文章

  1. Scala:First Steps in Scala
  2. 从服务器上的数据库备份到本地
  3. (c语言)二叉树中序线索(数据结构十七)
  4. 开发Android应用 提升性能的小技巧
  5. android wifi
  6. 《那些年啊,那些事——一个程序员的奋斗史》——35
  7. java注解类型_Java注解类型
  8. powerpoint预览_如何放大和缩小PowerPoint演示文稿的一部分
  9. 如何将Apple Mail建议用于事件和联系人
  10. mac共享单个磁盘_如何与您的所有设备共享酒店的单个Wi-Fi连接