鏈接:https://gitee.com/zhang_jun_xin/flink-recommandSystem-demo
商品實(shí)時(shí)推薦系統(tǒng)
1. 系統(tǒng)架構(gòu) v2.0
-
1.1 系統(tǒng)架構(gòu)圖
image 1.2模塊說明
-
a.在日志數(shù)據(jù)模塊(flink-2-hbase)中,又主要分為6個(gè)Flink任務(wù):
-
用戶-產(chǎn)品瀏覽歷史 -> 實(shí)現(xiàn)基于協(xié)同過濾的推薦邏輯
通過Flink去記錄用戶瀏覽過這個(gè)類目下的哪些產(chǎn)品,為后面的基于Item的協(xié)同過濾做準(zhǔn)備 實(shí)時(shí)的記錄用戶的評分到Hbase中,為后續(xù)離線處理做準(zhǔn)備.
數(shù)據(jù)存儲(chǔ)在Hbase的p_history表
-
用戶-興趣 -> 實(shí)現(xiàn)基于上下文的推薦邏輯
根據(jù)用戶對同一個(gè)產(chǎn)品的操作計(jì)算興趣度,計(jì)算規(guī)則通過操作間隔時(shí)間(如購物 - 瀏覽 < 100s)則判定為一次興趣事件 通過Flink的ValueState實(shí)現(xiàn),如果用戶的操作Action=3(收藏),則清除這個(gè)產(chǎn)品的state,如果超過100s沒有出現(xiàn)Action=3的事件,也會(huì)清除這個(gè)state
數(shù)據(jù)存儲(chǔ)在Hbase的u_interest表
-
用戶畫像計(jì)算 -> 實(shí)現(xiàn)基于標(biāo)簽的推薦邏輯
v1.0按照三個(gè)維度去計(jì)算用戶畫像,分別是用戶的顏色興趣,用戶的產(chǎn)地興趣,和用戶的風(fēng)格興趣.根據(jù)日志不斷的修改用戶畫像的數(shù)據(jù),記錄在Hbase中.
數(shù)據(jù)存儲(chǔ)在Hbase的user表
-
產(chǎn)品畫像記錄 -> 實(shí)現(xiàn)基于標(biāo)簽的推薦邏輯
用兩個(gè)維度記錄產(chǎn)品畫像,一個(gè)是喜愛該產(chǎn)品的年齡段,另一個(gè)是性別
數(shù)據(jù)存儲(chǔ)在Hbase的prod表
-
事實(shí)熱度榜 -> 實(shí)現(xiàn)基于熱度的推薦邏輯
通過Flink時(shí)間窗口機(jī)制,統(tǒng)計(jì)當(dāng)前時(shí)間的實(shí)時(shí)熱度,并將數(shù)據(jù)緩存在Redis中.
通過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í)間,行為(如購買,點(diǎn)擊,推薦等).
數(shù)據(jù)按時(shí)間窗口統(tǒng)計(jì)數(shù)據(jù)大屏需要的數(shù)據(jù),返回前段展示
數(shù)據(jù)存儲(chǔ)在Hbase的con表
-
-
b. web模塊
-
前臺(tái)用戶界面
該頁面返回給用戶推薦的產(chǎn)品list
-
后臺(tái)監(jiān)控頁面
該頁面返回給管理員指標(biāo)監(jiān)控
-
2.推薦引擎邏輯說明
-
2.1 基于熱度的推薦邏輯
現(xiàn)階段推薦邏輯圖
? 根據(jù)用戶特征种吸,重新排序熱度榜,之后根據(jù)兩種推薦算法計(jì)算得到的產(chǎn)品相關(guān)度評分呀非,為每個(gè)熱度榜中的產(chǎn)品推薦幾個(gè)關(guān)聯(lián)的產(chǎn)品
-
2.2 基于產(chǎn)品畫像的產(chǎn)品相似度計(jì)算方法
基于產(chǎn)品畫像的推薦邏輯依賴于產(chǎn)品畫像和熱度榜兩個(gè)維度,產(chǎn)品畫像有三個(gè)特征,包含color/country/style三個(gè)角度,通過計(jì)算用戶對該類目產(chǎn)品的評分來過濾熱度榜上的產(chǎn)品
image在已經(jīng)有產(chǎn)品畫像的基礎(chǔ)上,計(jì)算item與item之間的關(guān)聯(lián)系,通過余弦相似度來計(jì)算兩兩之間的評分,最后在已有物品選中的情況下推薦關(guān)聯(lián)性更高的產(chǎn)品.
相似度 | A | B | C |
---|---|---|---|
A | 1 | 0.7 | 0.2 |
B | 0.7 | 1 | 0.6 |
C | 0.2 | 0.6 | 1 |
-
2.3 基于協(xié)同過濾的產(chǎn)品相似度計(jì)算方法
根據(jù)產(chǎn)品用戶表(Hbase) 去計(jì)算公式得到相似度評分:
[圖片上傳失敗...(image-8cb878-1578644363134)]
3. 前臺(tái)推薦頁面
? 當(dāng)前推薦結(jié)果分為3列,分別是熱度榜推薦,協(xié)同過濾推薦和產(chǎn)品畫像推薦
[圖片上傳失敗...(image-8a047b-1578644363136)]
4. 后臺(tái)數(shù)據(jù)大屏
? 在后臺(tái)上顯示推薦系統(tǒng)的實(shí)時(shí)數(shù)據(jù),數(shù)據(jù)來自其他Flink計(jì)算模塊的結(jié)果.目前包含熱度榜和1小時(shí)日志接入量兩個(gè)指標(biāo). 真實(shí)數(shù)據(jù)位置在resource/database.sql
5. 部署說明
以下的部署均使用Docker坚俗,對于搭建一套復(fù)雜的系統(tǒng),使用docker來部署各種服務(wù)中間件再合適不過了岸裙。這里有一套簡單的Docker入門系列
需要的服務(wù)有:Mysql猖败、Redis、Hbase和Kafka
Mysql
<pre style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; overflow-wrap: normal; padding: 16px; line-height: 1.45; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; tab-size: 4; color: rgb(51, 51, 51);">docker pull mysql:5.7
docker run --name local-mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7</pre>
簡單介紹一下命令降允,先拉取鏡像恩闻,然后指定參數(shù)啟動(dòng)容器
-
--name local-mysql
容器名為local-mysql -
-p 3308:3306
宿主機(jī)與容器的端口映射為3308:3306 即你訪問宿主機(jī)的3308就是訪問容器的3306端口,需要理解下 -
-e MYSQL_ROOT_PASSWORD=123456
容器內(nèi)的變量名MYSQL_ROOT_PASSWORD
對應(yīng)的值為123456 即mysql的root密碼為123456 -
-d
后臺(tái)啟動(dòng)
Redis
<pre style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; overflow-wrap: normal; padding: 16px; line-height: 1.45; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; tab-size: 4; color: rgb(51, 51, 51);">$ docker run --name local-redis -p 6379:6379 -d redis</pre>
Hbase
<pre style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; overflow-wrap: normal; padding: 16px; line-height: 1.45; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; tab-size: 4; color: rgb(51, 51, 51);">docker pull harisekhon/hbase
docker run -d -h base-server
-p 2181:2181
-p 8080:8080
-p 8085:8085
-p 9090:9090
-p 9000:9000
-p 9095:9095
-p 16000:16000
-p 16010:16010
-p 16201:16201
-p 16301:16301
-p 16020:16020
--name hbase
harisekhon/hbase
</pre>
Hbase用到的端口,可以參考一下詳細(xì)教程 啟動(dòng)成功之后我們可以訪問http://localhost:16010/master-status
登錄Web界面
快速實(shí)現(xiàn)SpringBoot集成Hbase
Kafka
考慮到更好的區(qū)別這些端口剧董,我這里啟動(dòng)了一個(gè)虛擬機(jī)幢尚,在虛擬機(jī)中在用dokcer安裝Kafka破停,過程如下
<pre style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; overflow-wrap: normal; padding: 16px; line-height: 1.45; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; tab-size: 4; color: rgb(51, 51, 51);">## pull images
docker pull wurstmeister/zookeeper
docker pull wurstmeister/kafka
docker pull sheepkiller/kafka-manager
docker run -d --name zookeeper --publish 2181:2181
--volume /etc/localtime:/etc/localtime
--restart=always
wurstmeister/zookeeper
run kafka
docker run --name kafka
-p 9092:9092
--link zookeeper:zookeeper
-e KAFKA_ADVERTISED_HOST_NAME=192.168.1.8
-e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
-d wurstmeister/kafka
run kafka manager
docker run -d
--link zookeeper:zookeeper
-p 9000:9000
-e ZK_HOSTS="zookeeper:2181"
hlebalbau/kafka-manager:stable
-Dpidfile.path=/dev/null</pre>
如果想設(shè)置webui 的權(quán)限,可以這樣設(shè)置
<pre style="box-sizing: border-box; overflow: auto; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; overflow-wrap: normal; padding: 16px; line-height: 1.45; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal; tab-size: 4; color: rgb(51, 51, 51);">KAFKA_MANAGER_AUTH_ENABLED: "true"
KAFKA_MANAGER_USERNAME: username
KAFKA_MANAGER_PASSWORD: password</pre>
容器啟動(dòng)成功之后就可以在頁面訪問localhost:9000
查看Kafkfa的管理界面尉剩。
快速實(shí)現(xiàn)SpringBoot集成Kafka
啟動(dòng)服務(wù)
以下的操作是在IDEA下完成
1辱挥、將上述部署的幾個(gè)服務(wù)的ip和端口號分別配置在flink-2-hbase和web服務(wù)中;
2、在flink-2-hbase中的根目錄執(zhí)行mvn clean install
边涕,目的是將其打包并放置在本地倉庫中;
3晤碘、分別啟動(dòng)task目錄下的task(直接在idea中右鍵啟動(dòng)就行了);
4、把SchedulerJob啟動(dòng)起來功蜓,定時(shí)的去計(jì)算協(xié)同過濾和用戶畫像所需要的分?jǐn)?shù);
5园爷、在idea中打開web項(xiàng)目,等待其自動(dòng)引入flink-2-hbase生成的jar包之后式撼,再啟動(dòng)服務(wù)就ok了童社;
注意: 所有的服務(wù)啟動(dòng)后,因?yàn)闆]有任何的點(diǎn)擊記錄著隆,所以就是隨機(jī)從數(shù)據(jù)庫取得產(chǎn)品扰楼,這里需要你在推薦頁面隨便點(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)