生產(chǎn)實踐 | Flink + 直播(二)| 如何建設(shè)實時公共畫像維表?

本系列每篇文章都是從一些實際生產(chǎn)實踐需求出發(fā)岳悟,解決一些生產(chǎn)實踐中的問題佃迄,拋磚引玉,以幫助小伙伴們解決一些實際生產(chǎn)問題贵少。本篇文章主要介紹直播間畫像實時維表建設(shè)的整個過程呵俏,如果對小伙伴有幫助的話,歡迎點贊 + 再看~

技術(shù)架構(gòu)

回顧上一節(jié)的技術(shù)架構(gòu)圖滔灶。

tec-arc.png

整個架構(gòu)相對來說是比較好理解的普碎。從數(shù)據(jù)源到數(shù)據(jù)處理以及最后到數(shù)據(jù)匯部分。

但是大家的疑惑點可能就集中在三個維表的建設(shè)上录平,包含主播用戶畫像維表麻车,觀眾用戶畫像維表缀皱,直播間畫像維表

dim-tec-arc.png

我們依然從以下幾個角度的問題出發(fā)动猬,通過分析場景啤斗,解答這幾個問題來給大家介紹以上三個維表的建設(shè)過程。

Question

  • WHAT:直播實時公共畫像維表是指什么枣察?離線公共畫像維表又指什么争占?區(qū)別?
  • WHY:為什么架構(gòu)圖中的三類公共畫像維表要按照實時和離線進行劃分序目?為什么需要建設(shè)實時公共畫像維表臂痕,離線公共畫像維表不能滿足需求?
  • HOW:怎樣才能建設(shè)滿足直播實時數(shù)據(jù)的實時公共畫像維表猿涨?
  • WHO:需要使用什么樣的組件建設(shè)直播實時公共畫像維表握童?為什么選用這些組件進行建設(shè)?

WHAT:實時 & 離線公共畫像維表叛赚?

概念

首先簡單介紹下澡绩,實時 & 離線公共畫像維表中存儲的內(nèi)容就是實體的固有屬性(比如用戶的年齡等),我理解這兩個詞本身是高層抽象的概念俺附,本文中介紹的主播用戶畫像維表肥卡,觀眾用戶畫像維表,直播間畫像維表是其具體實現(xiàn)事镣。

其他大佬的文章解釋中會對實時公共畫像維表 & 離線公共畫像維表有更加深度的理解步鉴,這里我只說明我在直播實時數(shù)據(jù)建設(shè)過程中的理解~

區(qū)別

其實這兩個詞的區(qū)別從名字上就可以區(qū)分出來,實時公共畫像維表和離線公共畫像維表的最大區(qū)別就是數(shù)據(jù)建設(shè)和應(yīng)用場景要求的時效性不同璃哟。

離線公共畫像維表

特點:

  • 場景:適合離線場景氛琢,時效性要求比較弱的場景,為指標提供畫像維度填充或者打標服務(wù)
  • 建設(shè):一般都是以離線 t + 1 的方式進行建設(shè)
  • 應(yīng)用:使用的數(shù)據(jù)為離線 t + 1 的數(shù)據(jù)
  • 舉例:數(shù)據(jù)倉庫中的用戶畫像維表随闪,為應(yīng)用層數(shù)據(jù)提供畫像服務(wù)阳似;比如不但需要統(tǒng)計總 uv,還需要統(tǒng)計分年齡段的 uv铐伴。

實時公共畫像維表

特點:

  • 場景:適合實時場景撮奏,時效性要求比較強的場景,為指標提供畫像維度填充或者打標服務(wù)
  • 建設(shè):實時的進行建設(shè)盛杰,延遲一般在秒級別
  • 應(yīng)用:使用的數(shù)據(jù)都是實時建設(shè)好的挽荡,必須可以實時獲取(秒級別延遲后獲取到)并使用

WHY:為什么建設(shè)實時公共畫像維表即供?

為什么架構(gòu)圖中的三類公共畫像維表要按照實時和離線進行劃分定拟?為什么需要建設(shè)實時公共畫像維表,離線公共畫像維表不能滿足需求?

這幾個問題其實圍繞著我們的直播實時數(shù)據(jù)建設(shè)以及應(yīng)用的場景就可以展開解答青自。

接上篇技術(shù)架構(gòu)圖株依,其中直播實時數(shù)據(jù)需要建設(shè)的公共維表分為以下三類:

  • 直播間畫像維表:包含直播對應(yīng)的直播類別、開播客戶端延窜、標題恋腕、開播地址等信息
  • 主播畫像維表:主播對應(yīng)的主播名、主播類別逆瑞、性別荠藤、年齡段等
  • 觀眾畫像維表:觀眾對應(yīng)的觀眾性別、年齡段等

直播間畫像維表

首先拋出結(jié)論:直播間畫像都是直播間的固有屬性畫像获高,直播間畫像維表的建設(shè)過程是實時的哈肖。

由于大多數(shù)直播的時長都在幾小時不等,隨著直播的開始念秧,主播域觀眾的互動也隨即產(chǎn)生淤井,從而直播生產(chǎn)和消費的指標也開始產(chǎn)出,隨著直播的結(jié)束摊趾,主播和觀眾的互動也就結(jié)束了币狠,對應(yīng)的直播生產(chǎn)和消費指標也就不存在了,因此直播間畫像的所能提供給其他指標作為維表的價值也就快速消失了砾层,所以直播間畫像(標題漩绵,開播地址)的應(yīng)用場景特點就是時效性很強
因此直播間畫像維表對于直播生產(chǎn)消費指標的建設(shè)和應(yīng)用來說肛炮,需要滿足可實時建設(shè)渐行、可實時查詢獲取的要求。

主播 & 觀眾用戶畫像維表

結(jié)論:這類畫像都是用戶的固有屬性畫像铸董,而非直播間固有屬性,和直播間是非強相關(guān)的肴沫。主播 & 觀眾用戶畫像維表的建設(shè)過程可以是離線的粟害。

無論直播間的開播關(guān)播,直播過程中的生產(chǎn)消費颤芬,主播畫像和觀眾畫像基本上不會產(chǎn)生變動悲幅。
(舉例:大多數(shù)情況下,當(dāng)已經(jīng)判定一個用戶的年齡段畫像為 18 - 23 時站蝠,即使這個用戶開了 10 場直播汰具,或者這個用戶觀看了 10 場直播,其年齡段判定也基本不會有變化)菱魔。
因此主播用戶畫像維表 & 觀眾用戶畫像維表對于直播生產(chǎn)消費指標的建設(shè)和應(yīng)用來說留荔,可以滿足離線 t + 1 建設(shè),提供數(shù)據(jù)服務(wù)進行實時獲取的要求澜倦。

Notes:

主播 & 觀眾用戶畫像需要根據(jù)用戶生產(chǎn)消費行為以及其他信息聚蝶,使用到機器學(xué)習(xí)進行性別和年齡段等的用戶畫像信息判定產(chǎn)出杰妓。
也有非常多的場景將這類畫像進行實時建設(shè),用于實時個性化推薦等碘勉。只不過本文的直播實時數(shù)據(jù)建設(shè)對于這兩類畫像的時效性要求較弱巷挥,所以采用了離線的方式進行建設(shè)。

HOW + WHO:怎樣建設(shè)验靡?用什么建設(shè)倍宾?

直播間生命周期 & 數(shù)據(jù)流轉(zhuǎn)

直播間整個生命周期如圖所示。

live-stream-life-cycle.png
  • 1.主播創(chuàng)建直播間胜嗓,直播間進入開播的狀態(tài)高职;
  • 2.觀眾進入直播間后,在直播間內(nèi)與主播進行互動兼蕊;
  • 3.最后就是主播對直播間進行關(guān)播初厚,標識著直播間生命周期的結(jié)束狀態(tài)。

直播間畫像維表-實時

實時畫像維表的建設(shè)孙技。上圖中紅色的字體為實時畫像維表的建設(shè)和應(yīng)用過程产禾。

直播間畫像實時數(shù)據(jù)流轉(zhuǎn)

  • 1.當(dāng)主播開播,直播間進行直播后牵啦,直播間產(chǎn)生了直播間畫像信息亚情,這時可以將畫像信息實時的建設(shè)到直播間畫像實時維表中。
    并且可以同時建設(shè)生產(chǎn)側(cè)的實時指標哈雏,利用建設(shè)好的直播間畫像實時維表 + 主播 & 觀眾畫像離線維表進行生產(chǎn)側(cè)指標的維度填充楞件;
  • 2.當(dāng)觀眾進入直播間后,與主播進行互動裳瘪,產(chǎn)生一系列的消費行為土浸,隨即可以建設(shè)消費側(cè)的實時指標,利用建設(shè)的直播間畫像實時維表 + 主播 & 觀眾畫像離線維表進行消費側(cè)指標的維度填充彭羹;
  • 3.當(dāng)主播對直播間進行關(guān)播的時候黄伊,從直播間畫像實時維表中就可以對該直播間的畫像進行刪除。

組件選型

通過上文的分析派殷,可以了解到直播間畫像實時維表建設(shè)的要求如下:

  • 實時畫像:首先需要支持實時建設(shè)还最,實時訪問;
  • 實時畫像:建設(shè)的數(shù)據(jù)都為實時指標毡惜,即要求低延遲的請求響應(yīng)時間拓轻;
  • 公共畫像:需要支撐多個大流量生產(chǎn)消費實時任務(wù)的訪問請求,即提供高 QPS 畫像數(shù)據(jù)服務(wù)经伙;
  • 公共畫像:高穩(wěn)定性扶叉。

因此組件選型就自然落在了高速緩存的范疇中,我們最后經(jīng)過方案對比之后,選擇了 redis 作為我們的實時維表的存儲引擎辜梳。

使用了 redis 中的 hash 作為維表存儲結(jié)構(gòu)粱甫,其中直播間畫像維度存儲設(shè)計如下圖。

live-stream-dim-redis-hash.png

flink 實時維表建設(shè)代碼示例

public class LiveStreamRealtimeDimBuilderJob {

    public static void main(String[] args) throws Exception {
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<byte[]> source = SourceFactory.getSourceDataStream();
        source.process(new ProcessFunction<byte[], String>() {
            @Override
            public void processElement(byte[] bytes, Context context, Collector<String> collector) throws Exception {
                CommonModel c = CommonModel.parseFrom(bytes);
                // 開播
                if (c.isStartLiveStream()) {
                    RedisConfig
                            .get()
                            .hmset(c.getLiveStreamId()
                                    , ImmutableMap.<String, String>builder()
                                            .put("type", c.getType())
                                            .put("client", c.getClient())
                                            .put("title", c.getTitle())
                                            .put("address", c.getAddress())
                                            .build()
                            );
                    RedisConfig
                            .get()
                            .expire(c.getLiveStreamId(), 30 * 24 * 60 * 60);
                } else if (c.isEndLiveStream()) {
                // 關(guān)播
                    RedisConfig
                            .get()
                            .expire(c.getLiveStreamId(), 2 * 24 * 60 * 60);
                }
            }
        });

        env.execute();
    }

    @Data
    public static class CommonModel {
        private String liveStreamId; // 直播間 id
        private String type; // 直播間類型
        private String client; // 開播客戶端
        private String title; // 直播間標題
        private String address; // 直播間開播地址

        public static CommonModel parseFrom(byte[] bytes) {
            // 邏輯根據(jù)業(yè)務(wù)邏輯判定
            return null;
        }

        public boolean isStartLiveStream() {
            // 邏輯根據(jù)業(yè)務(wù)邏輯判定
            return false;
        }

        public boolean isEndLiveStream() {
            // 邏輯根據(jù)業(yè)務(wù)邏輯判定
            return false;
        }
    }
}

主播 & 觀眾用戶畫像維表-離線

離線畫像維表的建設(shè)作瞄。主要包含主播和觀眾的用戶畫像茶宵,性別,年齡等信息宗挥。如下圖藍色的字體為離線畫像維表的應(yīng)用過程乌庶。

live-stream-life-cycle.png

主播 & 觀眾畫像數(shù)據(jù)流轉(zhuǎn)

在產(chǎn)出直播間生產(chǎn)側(cè)、消費側(cè)實時數(shù)據(jù)時契耿,使用主播 & 觀眾畫像進行了畫像維度填充瞒大。

存儲組件

其中離線畫像維表的存儲組件選型與實時相同,同為 redis搪桂,畫像信息存儲方式也是使用 redis hash 結(jié)構(gòu)進行存儲透敌。

以 t + 1 的方式進行畫像數(shù)據(jù)建設(shè)并進行數(shù)據(jù)同步,將建設(shè)好的全量主播和觀眾用戶畫像同步到 redis 高速緩存當(dāng)中踢械。

總結(jié)

本文銜接上文酗电,主要介紹直播間實時維表的建設(shè)過程。提出幾個建設(shè)的問題内列,以這幾個問題出發(fā)撵术,引出了一下三小節(jié)。

第一節(jié)簡單介紹了實時 & 離線公共畫像維表的概念话瞧。

第二節(jié)從數(shù)據(jù)應(yīng)用場景的角度出發(fā)嫩与,介紹了為什么需要建設(shè)實時的公共畫像維表。

第三節(jié)主要介紹了實時畫像維表的建設(shè)過程以及詳細的技術(shù)方案交排。

最后一節(jié)對本文進行了總結(jié)划滋。

如果你也建設(shè)過實時畫像維表,或者有相同的需求埃篓,歡迎留言或者留下你的文章鏈接古毛,相互交流~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市都许,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嫂冻,老刑警劉巖胶征,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異桨仿,居然都是意外死亡睛低,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钱雷,“玉大人骂铁,你說我怎么就攤上這事≌挚梗” “怎么了拉庵?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長套蒂。 經(jīng)常有香客問我钞支,道長,這世上最難降的妖魔是什么操刀? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任烁挟,我火速辦了婚禮,結(jié)果婚禮上骨坑,老公的妹妹穿的比我還像新娘撼嗓。我一直安慰自己,他們只是感情好欢唾,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布且警。 她就那樣靜靜地躺著,像睡著了一般匈辱。 火紅的嫁衣襯著肌膚如雪振湾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天亡脸,我揣著相機與錄音押搪,去河邊找鬼。 笑死浅碾,一個胖子當(dāng)著我的面吹牛大州,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垂谢,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼厦画,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了滥朱?” 一聲冷哼從身側(cè)響起根暑,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎徙邻,沒想到半個月后排嫌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡缰犁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年淳地,在試婚紗的時候發(fā)現(xiàn)自己被綠了怖糊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡颇象,死狀恐怖伍伤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情遣钳,我是刑警寧澤扰魂,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站耍贾,受9級特大地震影響阅爽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荐开,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一付翁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晃听,春花似錦百侧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至初斑,卻和暖如春辛润,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背见秤。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工砂竖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹃答。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓乎澄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親测摔。 傳聞我的和親對象是個殘疾皇子置济,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354