<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          程序員過關(guān)斬將--從每秒6000寫請求談起

          共 2475字,需瀏覽 5分鐘

           ·

          2020-03-09 23:23



          作者丨菜v菜來源丨架構(gòu)師修行之路

          菜菜哥,緊急求助呀

          2b2e01d16d98cafe8e14fb6fb79f4d6c.webp805e9c5df6d1bcf2d9b36038c180f65e.webp

          怎么回事?產(chǎn)品經(jīng)理砍你了?

          5125fe9c5592db565a6db4e4abf562c2.webp8ea9d477dcc60603185e45fbf65e38dc.webp

          沒有,只是寫了個新項(xiàng)目,上線就被壓垮了

          2b2e01d16d98cafe8e14fb6fb79f4d6c.webp805e9c5df6d1bcf2d9b36038c180f65e.webp

          什么功能,這么強(qiáng)悍?

          5125fe9c5592db565a6db4e4abf562c2.webp8ea9d477dcc60603185e45fbf65e38dc.webp

          一個記錄用戶觀看視頻進(jìn)度信息的功能

          2b2e01d16d98cafe8e14fb6fb79f4d6c.webp805e9c5df6d1bcf2d9b36038c180f65e.webp

          那如果用戶基數(shù)大,確實(shí)是需要注意的,那我給你分析一下哈

          5125fe9c5592db565a6db4e4abf562c2.webp8ea9d477dcc60603185e45fbf65e38dc.webp7d3485771eb0c0be95e23b25a0b18627.webp背景
          3c2dead7716b76152f61c8fd067bee15.webp每一個片子的幕后,都保留了你的觀看記錄,詳細(xì)的記著你觀看了幾次,跳過了那些時長 ,據(jù)說根據(jù)這些數(shù)據(jù)可以分析出你喜歡哪個日本明星,以此來做定向推送......d9ae5666f036558dd649b87b3db7f29d.webp雖然看起來很簡單的一個功能,其實(shí)涉及到的數(shù)據(jù)量非常大,極限情況下為你的用戶數(shù)*視頻數(shù)的乘積。
          那么在只有兩個網(wǎng)站服務(wù)器,一臺sqlserver的情況下,該如何面對這樣不算大數(shù)據(jù)量的寫請求呢?為什么說是寫請求呢?因?yàn)橛脩粲^看視頻的每一秒你都需要記錄下來,例如:視頻的第十秒用戶觀看了。要想把這個功能搞定,首先需要定義幾個事情:1. 記錄用戶觀看視頻情況的數(shù)據(jù)定義2. 和客戶端交互的數(shù)據(jù)協(xié)議3. 數(shù)據(jù)庫中記錄的數(shù)據(jù)格式4. 如何解決服務(wù)器寫的壓力(畢竟單臺服務(wù)器請求數(shù)還是比較大)
          7d3485771eb0c0be95e23b25a0b18627.webp解決方案

          用戶觀看視頻進(jìn)度定義

          3c2dead7716b76152f61c8fd067bee15.webp對于一個視頻來說,假如有1個小時的時長,這3600秒對應(yīng)著3600個是否已經(jīng)觀看的狀態(tài),對于觀看狀態(tài)來說,只有觀看和未觀看兩種狀態(tài),所以一個bit足以,一個字節(jié)(byte)有8個bit,所以一個byte可以表示8秒的觀看狀態(tài),以此為基礎(chǔ),進(jìn)制越高,同樣數(shù)量的字符表示的狀態(tài)就越多。客戶端每次上傳新的數(shù)據(jù),需要和服務(wù)端已經(jīng)存在的數(shù)據(jù)做位運(yùn)算,例如:01000? 表示第二秒觀看了 ,客戶端新上傳:00011 表示第4,5秒都觀看了,對于用戶而言這個視頻第2,4,5 秒都看過,雖然只是一個簡單的運(yùn)算,但是量大的時候,對cpu的消耗不容小覷。
          第一字節(jié)????第二字節(jié)
          ??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
          二進(jìn)制:??0x88 ???0x40
          字符串:? 8840

          和客戶端交互協(xié)議

          3c2dead7716b76152f61c8fd067bee15.webp用戶觀看視頻的進(jìn)度實(shí)時信息,只有客戶端知道,客戶端需要上傳用戶的觀看進(jìn)度數(shù)據(jù),和服務(wù)端交互的進(jìn)制可以選擇通用性比較強(qiáng)的16進(jìn)制,當(dāng)然你選擇100進(jìn)制也無所謂,只要雙方能同時支持,并且能正常解析即可

          數(shù)據(jù)庫數(shù)據(jù)格式

          3c2dead7716b76152f61c8fd067bee15.webp每種數(shù)據(jù)庫支持的數(shù)據(jù)類型有差異,所以這里不在過多敘述,當(dāng)然無論什么格式,占用空間越少越好,但也要根據(jù)業(yè)務(wù)的計(jì)算量來綜合考慮。7d3485771eb0c0be95e23b25a0b18627.webp解決問題

          cpu性能問題

          3c2dead7716b76152f61c8fd067bee15.webp畢竟要把用戶每次最新的觀看數(shù)據(jù)和老數(shù)據(jù)做合并工作,在用戶量大的情況下不容小覷。在綜合了各種條件之后,最終采用10進(jìn)制來做合并工作,客戶端上傳上來16進(jìn)制數(shù)據(jù),然后轉(zhuǎn)化為十進(jìn)制,然后和觀看記錄(10進(jìn)制)做合并運(yùn)算,這部分cpu省略不了,具體轉(zhuǎn)化程序?yàn)椋?/span>
          //需要新加的數(shù)據(jù)
          ????????ConcurrentQueue?AddQueue?=?new?ConcurrentQueue();

          //把16進(jìn)制的字符串按照兩位?分割成十進(jìn)制數(shù)組
          ????????protected?List<int>?ConvertToProgressArray(string?progressString)
          ????????
          {
          ????????????if?(string.IsNullOrWhiteSpace(progressString))
          ????????????{
          ????????????????return?null;
          ????????????}
          ????????????//驗(yàn)證是否為2的倍數(shù)長度
          ????????????if?(progressString.Length?%?2?!=?0)
          ????????????{
          ????????????????return?null;
          ????????????}
          ????????????var?proStrSpan?=?progressString.AsSpan();
          ????????????List<int>?ret?=?new?List<int>();

          ????????????int?i?=?0;
          ????????????while?(i?????????????{
          ????????????????ret.Add(int.Parse(proStrSpan.Slice(i,?2).ToString(),?System.Globalization.NumberStyles.HexNumber));?;
          ????????????????i?=?i?+?2;
          ????????????}
          ????????????return?ret;
          ????????}

          客戶端請求數(shù)量問題

          3c2dead7716b76152f61c8fd067bee15.webp如果同時一萬用戶在同時觀看視頻,上傳數(shù)據(jù)時間間隔為2秒,意味著每秒有5000請求。由于這個業(yè)務(wù)只是一個用戶log型業(yè)務(wù),何為log型,就是說可以容忍一部分?jǐn)?shù)據(jù)丟失,針對這個數(shù)據(jù)形態(tài),客戶端可以先在本地做緩沖記錄,沒有必要一秒上傳一次記錄,例如現(xiàn)在約定的客戶端30秒上傳一次記錄,如果用戶關(guān)掉客戶端,下次啟動的時候會重新上傳未成功的記錄。

          數(shù)據(jù)庫壓力

          3c2dead7716b76152f61c8fd067bee15.webp如果每次請求都單獨(dú)更新數(shù)據(jù)庫,按照第二條的計(jì)算每秒高達(dá)5000次update請求。用戶觀看每次視頻都加載內(nèi)存中緩存,仔細(xì)分析這種業(yè)務(wù),由于是log型數(shù)據(jù),所以每次你請求沒有必要都去更新數(shù)據(jù)庫,而是先更新了緩存,然后定時去更新數(shù)據(jù)庫。
          由于數(shù)據(jù)量的問題,所有的更新操作都會發(fā)送到一個任務(wù)隊(duì)列,隊(duì)列的執(zhí)行者會根據(jù)配置批量更新數(shù)據(jù)庫,這樣比單條更新數(shù)據(jù)庫性能要高很多,其實(shí)這種方案在很多l(xiāng)og型的業(yè)務(wù)中都有使用,批量更新對數(shù)據(jù)庫的壓力要小很多,代碼類似以下
          public?async?Task<int>?AddUserVideoData(UserVideoInfo?data,?DBProcessEnum?processType?=?DBProcessEnum.Update)
          ????????
          {
          ????????????if(processType==?DBProcessEnum.Add)
          ????????????{
          ????????????????AddQueue.Enqueue(data);
          ????????????}

          ????????????return?1;
          ????????}

          ?void?MulProcessData()
          ????????
          {
          ????????????//每次更新的條數(shù)
          ????????????int?maxNumber?=?50;
          ????????????List?data?=?new?List();
          ????????????while?(true)
          ????????????{
          ????????????????if?(data?==?null)
          ????????????????{
          ????????????????????data?=?new?List();
          ????????????????}
          ????????????????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;
          ????????????????????????????}
          ????????????????????????????//判斷是否有重復(fù)對象
          ????????????????????????????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)
          ????????????????{

          ????????????????}


          ????????????}
          ????????}

          7d3485771eb0c0be95e23b25a0b18627.webp寫在最后
          3c2dead7716b76152f61c8fd067bee15.webp其實(shí)這種高IO的操作用sqlserver這種關(guān)系型數(shù)據(jù)庫反而不好,Nosql在這種簡單高IO的情境下要很多,改天可以改為redis試一試,估計(jì)會比sqlserver要好很多。

          0f76187b62b8a382f808ef6caa2d5b70.webp

          近期精彩內(nèi)容推薦:??

          bcd0f60e6c02e1212644a01ead9b53a6.webp?有個程序媛上司是什么體驗(yàn)

          bcd0f60e6c02e1212644a01ead9b53a6.webp?一個天才程序員的黑幫大佬人生

          bcd0f60e6c02e1212644a01ead9b53a6.webp?200行Python代碼做一個換臉程序

          bcd0f60e6c02e1212644a01ead9b53a6.webp?在 IntelliJ IDEA 中使用 Git,太方便了!




          7d843899962f202f3102be79cd0c8ec0.webp

          在看點(diǎn)這里a5647cf69d27a99af70b6aaea263f5bb.webp好文分享給更多人↓↓

          瀏覽 41
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人人操av | 影音先锋内射麻豆 | 性爱网免费| 在线观看黄色视频网站 | 人操操操操操人人人 |