2016-02-12 282 views
3

我是公司提供約會服務的服務器工程師。 目前我正在爲我們的新推薦引擎建立一個PoC。 我嘗試使用neo4j。但是這個數據庫的性能不符合我們的需求。 我有強烈的感覺,我做錯了什麼,neo4j可以做得更好。 那麼有人可以給我一個建議,如何提高我的Cypher查詢的性能或如何以正確的方式調整neo4j? 我使用的是neo4j-enterprise-2.3.1,它在Amazon Linux上運行在c4.4xlarge實例上。 在我們的數據集中,每個用戶可以與其他用戶有4種類型的關係 - LIKE,DISLIKE,BLOCK和MATCH。 他也有像countryCode,生日和性別的屬性。neo4j的低性能

我使用neo4j-import工具將所有用戶和關係從RDBMS導入neo4j。 因此,每個用戶都是具有屬性的節點,每個引用都是一種關係。

從Neo4j的導入工具,該報告稱,:

節點,

性能和

關係

被導入。

所以這是巨大的DB :-)在我們的情況下,一些節點最多可以有30個000引出的關係..

我取得了Neo4j的3個指標:

Indexes 
ON :User(userId)   ONLINE 
ON :User(countryCode)  ONLINE 
ON :User(birthday)   ONLINE 

然後我試着在網上建立利用推薦引擎的查詢:

MATCH (me:User {userId: {source_user_id} })-[:LIKE | :MATCH]->()<-[:LIKE | :MATCH]-(similar:User) 
USING INDEX me:User(userId) 
USING INDEX similar:User(birthday) 
WHERE similar.birthday >= {target_age_gte} AND 
     similar.birthday <= {target_age_lte} AND 
     similar.countryCode = {target_country_code} AND 
     similar.gender = {source_gender} 
WITH similar, count(*) as weight ORDER BY weight DESC 
SKIP {skip_similar_person} LIMIT {limit_similar_person} 
MATCH (similar)-[:LIKE | :MATCH]-(recommendation:User) 
WITH recommendation, count(*) as sheWeight 
WHERE recommendation.birthday >= {recommendation_age_gte} AND 
     recommendation.birthday <= {recommendation_age_lte} AND 
     recommendation.gender= {target_gender} 
WITH recommendation, sheWeight ORDER BY sheWeight DESC 
SKIP {skip_person} LIMIT {limit_person} 
MATCH (me:User {userId: {source_user_id} }) 
WHERE NOT ((me)--(recommendation)) 
RETURN recommendation 

這裏的執行計劃的用戶之一: plan

當我執行此查詢的用戶列表,我有結果:

count=2391, min=4565.128849, max=36257.170065, mean=13556.750555555178, stddev=2250.149335254768, median=13405.409811, p75=15361.353029999998, p95=17385.136478, p98=18040.900481, p99=18426.811424, p999=19506.149138, mean_rate=0.9957385490980866, m1=1.2148195797996817, m5=1.1418078036067119, m15=0.9928564378521962, rate_unit=events/second, duration_unit=milliseconds 

所以即使是最快的是實時推薦過慢..

你能告訴我我是什麼做錯了?

謝謝。

編輯1:計劃與擴展盒:plan

+0

你可以上傳計劃與盒子擴大呢? –

+0

上傳擴展計劃 – Mike

+0

嘿邁克,你可以給我發一封電子郵件,michael在neo4j.com,很想訪問你的數據庫來幫助你處理你的查詢。 –

回答

0

如果我讀這個權利,它是由userId找到了用戶的所有比賽和你不同的標準分別爲找到用戶的所有比賽。然後找到他們聚在一起的所有地方。

既然你有一個情況,你從一個節點開始左邊,我的猜測是,我們會更好地遵循路徑,然後過濾通過關係遍歷得到的東西。

讓我們看看如何開始這樣對你的作品:

MATCH 
    (me:User {userId: {source_user_id} })-[:LIKE | :MATCH]->() 
    <-[:LIKE | :MATCH]-(similar:User) 
WITH similar 
WHERE similar.birthday >= {target_age_gte} AND 
     similar.birthday <= {target_age_lte} AND 
     similar.countryCode = {target_country_code} AND 
     similar.gender = {source_gender} 
WITH similar, count(*) as weight ORDER BY weight DESC 
SKIP {skip_similar_person} LIMIT {limit_similar_person} 



MATCH (similar)-[:LIKE | :MATCH]-(recommendation:User) 
WITH recommendation, count(*) as sheWeight 
WHERE recommendation.birthday >= {recommendation_age_gte} AND 
     recommendation.birthday <= {recommendation_age_lte} AND 
     recommendation.gender= {target_gender} 
WITH recommendation, sheWeight ORDER BY sheWeight DESC 
SKIP {skip_person} LIMIT {limit_person} 
MATCH (me:User {userId: {source_user_id} }) 
WHERE NOT ((me)--(recommendation)) 
RETURN recommendation 
+0

嗨,布萊恩,謝謝你的回答。但是對於同一個用戶,你的方式慢15倍。這裏是[計劃](https://www.dropbox.com/s/ba0qmrvhp100gg0/plan%20%283%29.png?dl=0) – Mike

0

[增訂]

一個可能(和不直觀的)原因在查詢效率低下的是,當你指定similar:User(birthday)過濾器,Cypher使用索引搜索與:User(birthday)索引(以及其他測試countryCodegender)找到所有可能的 DB匹配similar。我們稱之爲similar節點的大集合A

只有找到A後,查詢過濾器才能查看哪些節點實際連接到me,如MATCH模式所指定的。

現在,如果有相對較少的mesimilar路徑(由MATCH模式指定,但沒有考慮到其WHERE條款)相比,A的大小 - 說,2首或更多個數量級的小 - 那麼從similar中刪除:User標籤可能會更快(因爲我認爲它們可能都是用戶,無論如何,在您的數據模型中),並且還刪除USING INDEX similar:User(birthday)子句。在這種情況下,不使用similar的索引實際上可能會更快,因爲您只會在相對較小的一組節點上使用WHERE子句。

同樣的考慮也適用於recommendation節點。

當然,這一切都必須通過測試您的實際數據進行驗證。

+0

刪除標籤以提高速度聽起來非常直觀 – manonthemat

+0

@cybersam感謝您的幫助,但此解決方案無效。刪除:用戶標籤增加了20次的工作量。 20 055 758總分貝擊中1 218 639爲同一個用戶...這裏是[計劃](https://www.dropbox.com/s/2zceyay7eq6iwst/plan%20%284%29.png?dl= 0) – Mike

+0

是的,我建議的答案確實取決於數據的特徵。我已經更新了我的答案,希望能更清楚一點。但不幸的是,它似乎對你的情況沒有幫助。 – cybersam

2

我構建了一個非託管擴展,以查看我能否比Cypher做得更好。你可以在這裏抓住它=>https://github.com/maxdemarzi/social_dna

這是第一槍,我們可以做一些事情來加快速度。我們可以預先計算/保存類似的用戶,在這裏和那裏緩存東西,以及隨機的其他技巧。試試看,讓我們知道它是如何發展的。

問候, 最大

+0

謝謝Max,這裏是你的擴展結果:'count = 67659,min = 66.381489,max = 2812.473438,mean = 1057.0306443213133,stddev = 507.4902115282372,median = 1021.305496,p75 = 1424.2454759999998,p95 = 1919.475549,p98 = 2159.701725, p99 = 2322.1246849999998,p999 = 2812.473438,mean_rate = 16.823460426561933,m1 = 14.954869485935108,m5 = 14.840333898992547,m15 = 14。832090331866569,rate_unit = events/second,duration_unit = milliseconds'這是非常令人印象深刻的! – Mike