基于 Flink 實(shí)現(xiàn)的商品實(shí)時(shí)推薦系統(tǒng)(附源碼)
之前一直給大家推薦的是關(guān)于 Flink 的介紹和知識(shí)點(diǎn),可以在歷史文章搜索了解。總的來(lái)說(shuō),現(xiàn)在還挺缺這種真正實(shí)戰(zhàn)的項(xiàng)目分享出來(lái),尤其是把源代碼分享出來(lái)的,近期我在 GitHub 觀察到一個(gè)不錯(cuò)的 Flink 項(xiàng)目,然后也和作者交流了下,于是在這里做一個(gè)分享。所以,那些平時(shí)問(wèn)我有沒(méi)有 Flink 項(xiàng)目的可以看過(guò)來(lái)了。地址在 :https://github.com/CheckChe0803/flink-recommandSystem-demo 下面介紹下這個(gè)項(xiàng)目。
1. 系統(tǒng)架構(gòu) v2.0
1.1 系統(tǒng)架構(gòu)圖

1.2模塊說(shuō)明
a.在日志數(shù)據(jù)模塊(flink-2-hbase)中,又主要分為6個(gè)Flink任務(wù):
用戶-產(chǎn)品瀏覽歷史 -> 實(shí)現(xiàn)基于協(xié)同過(guò)濾的推薦邏輯
通過(guò)Flink去記錄用戶瀏覽過(guò)這個(gè)類(lèi)目下的哪些產(chǎn)品,為后面的基于Item的協(xié)同過(guò)濾做準(zhǔn)備
實(shí)時(shí)的記錄用戶的評(píng)分到Hbase中,為后續(xù)離線處理做準(zhǔn)備.數(shù)據(jù)存儲(chǔ)在Hbase的p_history表
用戶-興趣 -> 實(shí)現(xiàn)基于上下文的推薦邏輯
根據(jù)用戶對(duì)同一個(gè)產(chǎn)品的操作計(jì)算興趣度,計(jì)算規(guī)則通過(guò)操作間隔時(shí)間(如購(gòu)物 - 瀏覽 < 100s)則判定為一次興趣事件
通過(guò)Flink的ValueState實(shí)現(xiàn),如果用戶的操作Action=3(收藏),則清除這個(gè)產(chǎn)品的state,如果超過(guò)100s沒(méi)有出現(xiàn)Action=3的事件,也會(huì)清除這個(gè)state數(shù)據(jù)存儲(chǔ)在Hbase的u_interest表
用戶畫(huà)像計(jì)算 -> 實(shí)現(xiàn)基于標(biāo)簽的推薦邏輯
v1.0按照三個(gè)維度去計(jì)算用戶畫(huà)像,分別是用戶的顏色興趣,用戶的產(chǎn)地興趣,和用戶的風(fēng)格興趣.根據(jù)日志不斷的修改用戶畫(huà)像的數(shù)據(jù),記錄在Hbase中.
數(shù)據(jù)存儲(chǔ)在Hbase的user表
產(chǎn)品畫(huà)像記錄 -> 實(shí)現(xiàn)基于標(biāo)簽的推薦邏輯
用兩個(gè)維度記錄產(chǎn)品畫(huà)像,一個(gè)是喜愛(ài)該產(chǎn)品的年齡段,另一個(gè)是性別
數(shù)據(jù)存儲(chǔ)在Hbase的prod表
事實(shí)熱度榜 -> 實(shí)現(xiàn)基于熱度的推薦邏輯
通過(guò)Flink時(shí)間窗口機(jī)制,統(tǒng)計(jì)當(dāng)前時(shí)間的實(shí)時(shí)熱度,并將數(shù)據(jù)緩存在Redis中.
通過(guò)Flink的窗口機(jī)制計(jì)算實(shí)時(shí)熱度,使用ListState保存一次熱度榜
數(shù)據(jù)存儲(chǔ)在redis中,按照時(shí)間戳存儲(chǔ)list
日志導(dǎo)入
從Kafka接收的數(shù)據(jù)直接導(dǎo)入進(jìn)Hbase事實(shí)表,保存完整的日志log,日志中包含了用戶Id,用戶操作的產(chǎn)品id,操作時(shí)間,行為(如購(gòu)買(mǎi),點(diǎn)擊,推薦等).
數(shù)據(jù)按時(shí)間窗口統(tǒng)計(jì)數(shù)據(jù)大屏需要的數(shù)據(jù),返回前段展示
數(shù)據(jù)存儲(chǔ)在Hbase的con表
b. web模塊
前臺(tái)用戶界面
該頁(yè)面返回給用戶推薦的產(chǎn)品list
后臺(tái)監(jiān)控頁(yè)面
該頁(yè)面返回給管理員指標(biāo)監(jiān)控
2.推薦引擎邏輯說(shuō)明
2.1 基于熱度的推薦邏輯
現(xiàn)階段推薦邏輯圖

根據(jù)用戶特征,重新排序熱度榜,之后根據(jù)兩種推薦算法計(jì)算得到的產(chǎn)品相關(guān)度評(píng)分,為每個(gè)熱度榜中的產(chǎn)品推薦幾個(gè)關(guān)聯(lián)的產(chǎn)品
2.2 基于產(chǎn)品畫(huà)像的產(chǎn)品相似度計(jì)算方法
基于產(chǎn)品畫(huà)像的推薦邏輯依賴(lài)于產(chǎn)品畫(huà)像和熱度榜兩個(gè)維度,產(chǎn)品畫(huà)像有三個(gè)特征,包含color/country/style三個(gè)角度,通過(guò)計(jì)算用戶對(duì)該類(lèi)目產(chǎn)品的評(píng)分來(lái)過(guò)濾熱度榜上的產(chǎn)品

在已經(jīng)有產(chǎn)品畫(huà)像的基礎(chǔ)上,計(jì)算item與item之間的關(guān)聯(lián)系,通過(guò)余弦相似度來(lái)計(jì)算兩兩之間的評(píng)分,最后在已有物品選中的情況下推薦關(guān)聯(lián)性更高的產(chǎn)品.

2.3 基于協(xié)同過(guò)濾的產(chǎn)品相似度計(jì)算方法
根據(jù)產(chǎn)品用戶表(Hbase) 去計(jì)算公式得到相似度評(píng)分:

3. 前臺(tái)推薦頁(yè)面
當(dāng)前推薦結(jié)果分為3列,分別是熱度榜推薦,協(xié)同過(guò)濾推薦和產(chǎn)品畫(huà)像推薦

4. 后臺(tái)數(shù)據(jù)大屏
在后臺(tái)上顯示推薦系統(tǒng)的實(shí)時(shí)數(shù)據(jù),數(shù)據(jù)來(lái)自其他Flink計(jì)算模塊的結(jié)果.目前包含熱度榜和1小時(shí)日志接入量?jī)蓚€(gè)指標(biāo).
真實(shí)數(shù)據(jù)位置在resource/database.sql

5. 部署說(shuō)明
以下的部署均使用Docker,對(duì)于搭建一套復(fù)雜的系統(tǒng),使用docker來(lái)部署各種服務(wù)中間件再合適不過(guò)了。這里有一套簡(jiǎn)單的Docker入門(mén)系列

需要的服務(wù)有:Mysql、Redis、Hbase和Kafka
Mysql
1docker pull mysql:5.7
2
3docker run --name local-mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
簡(jiǎn)單介紹一下命令,先拉取鏡像,然后指定參數(shù)啟動(dòng)容器
--name local-mysql容器名為local-mysql-p 3308:3306宿主機(jī)與容器的端口映射為3308:3306 即你訪問(wèn)宿主機(jī)的3308就是訪問(wèn)容器的3306端口,需要理解下-e MYSQL_ROOT_PASSWORD=123456容器內(nèi)的變量名MYSQL_ROOT_PASSWORD對(duì)應(yīng)的值為123456 即mysql的root密碼為123456-d后臺(tái)啟動(dòng)
Redis
1$ docker run --name local-redis -p 6379:6379 -d redis
Hbase
1docker pull harisekhon/hbase
2
3docker run -d -h base-server \
4 -p 2181:2181 \
5 -p 8080:8080 \
6 -p 8085:8085 \
7 -p 9090:9090 \
8 -p 9000:9000 \
9 -p 9095:9095 \
10 -p 16000:16000 \
11 -p 16010:16010 \
12 -p 16201:16201 \
13 -p 16301:16301 \
14 -p 16020:16020\
15 --name hbase \
16 harisekhon/hbase
Hbase用到的端口,可以參考一下詳細(xì)教程
啟動(dòng)成功之后我們可以訪問(wèn)http://localhost:16010/master-status登錄Web界面
:point_right: 快速實(shí)現(xiàn)SpringBoot集成Hbase
Kafka
考慮到更好的區(qū)別這些端口,我這里啟動(dòng)了一個(gè)虛擬機(jī),在虛擬機(jī)中在用dokcer安裝Kafka,過(guò)程如下
1## pull images
2docker pull wurstmeister/zookeeper
3docker pull wurstmeister/kafka
4docker pull sheepkiller/kafka-manager
5
6docker run -d --name zookeeper --publish 2181:2181 \
7 --volume /etc/localtime:/etc/localtime \
8 --restart=always \
9 wurstmeister/zookeeper
10
11
12## run kafka
13docker run --name kafka \
14 -p 9092:9092 \
15 --link zookeeper:zookeeper \
16 -e KAFKA_ADVERTISED_HOST_NAME=192.168.1.8 \
17 -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \
18 -d wurstmeister/kafka
19
20## run kafka manager
21docker run -d \
22 --link zookeeper:zookeeper \
23 -p 9000:9000 \
24 -e ZK_HOSTS="zookeeper:2181" \
25 hlebalbau/kafka-manager:stable \
26 -Dpidfile.path=/dev/null
如果想設(shè)置webui 的權(quán)限,可以這樣設(shè)置
1KAFKA_MANAGER_AUTH_ENABLED: "true"
2KAFKA_MANAGER_USERNAME: username
3KAFKA_MANAGER_PASSWORD: password
容器啟動(dòng)成功之后就可以在頁(yè)面訪問(wèn)localhost:9000查看Kafkfa的管理界面。
:point_right: 快速實(shí)現(xiàn)SpringBoot集成Kafka
啟動(dòng)服務(wù)
以下的操作是在IDEA下完成
1、將上述部署的幾個(gè)服務(wù)的ip和端口號(hào)分別配置在flink-2-hbase和web服務(wù)中;
2、在flink-2-hbase中的根目錄執(zhí)行mvn clean install,目的是將其打包并放置在本地倉(cāng)庫(kù)中;
3、分別啟動(dòng)task目錄下的task(直接在idea中右鍵啟動(dòng)就行了);
4、把SchedulerJob啟動(dòng)起來(lái),定時(shí)的去計(jì)算協(xié)同過(guò)濾和用戶畫(huà)像所需要的分?jǐn)?shù);
5、在idea中打開(kāi)web項(xiàng)目,等待其自動(dòng)引入flink-2-hbase生成的jar包之后,再啟動(dòng)服務(wù)就ok了;
注意:所有的服務(wù)啟動(dòng)后,因?yàn)闆](méi)有任何的點(diǎn)擊記錄,所以就是隨機(jī)從數(shù)據(jù)庫(kù)取得產(chǎn)品,這里需要你在推薦頁(yè)面隨便點(diǎn)擊,等有了一定的歷史數(shù)據(jù)之后,就能實(shí)現(xiàn)實(shí)時(shí)推薦的效果了
6. 下一步工作
添加flink任務(wù)監(jiān)控
完善數(shù)據(jù)大屏,顯示更詳細(xì)的指標(biāo)
統(tǒng)計(jì)召回率/準(zhǔn)確率等業(yè)務(wù)指標(biāo)
推薦閱讀:
世界的真實(shí)格局分析,地球人類(lèi)社會(huì)底層運(yùn)行原理
企業(yè)IT技術(shù)架構(gòu)規(guī)劃方案
論數(shù)字化轉(zhuǎn)型——轉(zhuǎn)什么,如何轉(zhuǎn)?
企業(yè)10大管理流程圖,數(shù)字化轉(zhuǎn)型從業(yè)者必備!
【中臺(tái)實(shí)踐】華為大數(shù)據(jù)中臺(tái)架構(gòu)分享.pdf
數(shù)字化轉(zhuǎn)型的本質(zhì)(10個(gè)關(guān)鍵詞)
