Neo4j之坑


10個月前,我開始用neo4j做cmdb. 初體驗下去neo4j很美好. 但是一年中發現一些問題, 僅僅是個人的體驗.經供參考

查詢語言

如果接觸過Neo4j,都會為Cypher的簡單和易用感覺到驚嘆, 向其他數據庫一樣,Neo4j也提供了ExplainProfile工具.這樣讓你容易理解查詢是如何運作的.如果你看過neo4j的查詢計划優化的圖,你會發現一大堆牽扯的線. 最開始簡單的查詢,一切都很美好.當業務需求越來雜,你用到的查詢越來越復雜,你就發現,天啊. 為什么我改了這么一小段代碼的順序,查詢慢了這么多. 所以官方也推薦你用多個小查詢替代一個大查詢. 所以你要遷移部分計算任務到你的代碼層,而不是通過Cypher再數據庫中幫你處理.

查詢的執行過程

查詢監視

你有沒有過這種情況, 本來你想查100條數據,但是你寫錯了,你寫成查1M條數據. 正常情況下,一般數據庫提供query watcher會阻止你這個查詢進行下去,因為這太耗內存,會讓數據庫都崩了. Neo4j里面也有這個東西,但是好像作用不穩定.最好的結果是你等待了很久得到了一個undefined--undefined. 更差的是數據庫崩了,再差一點,你的服務崩了.

讀優先

Neo4j有一個設定,就是任何對Node的操作,都要先把該node的值讀出來. 在關系型數據庫中,你要刪除一個表,是不需要讀取每一列的數據的.而在neo4j里面,你要這樣做. 所以如果你想要根據label比如Match (n:label) delete n.那你就要小心了.如果你這個label下有1M的node.那這個任務是無法完成的,因為你的機器RAM不夠大.會讓JVM GC-FULL. 所以同樣,你必須在代碼層做一些分塊刪除處理. 又增加了你的編碼難度.

Neo4j的鎖行為和關系型數據庫不大一樣.關系型數據中你做了一個更新操作,那么根據你是樂觀/悲觀. 或者一些策略,數據庫的查詢執行器會按照固定的套路進行查詢. 在Neo4j中.只有一個寫鎖.但這個寫鎖是在真的set語句開始執行的時候才加上去的. 比如match (n:label {id:1}) set n.param=2.這句話中只有match執行完了之后才會加上寫鎖. 這在並發更新的時候就會出現問題. 這在neo4j里面被討論的很多,很多人也提出了方案

連接

neo4j沒有連接池.而且也沒有參數限制數據庫連接數.很多時候這個問題會導致很多不穩定的情況發生.

擴展

因為用的是Neo4j3.3的版本.沒有全文檢索的功能.而需求又必須支持比較強大的查詢. 所以我需要一個搜索引擎. 我用了ES.但是我並不想在代碼層去做neo4j和ES的數據同步. 這樣又讓我的代碼復雜了. 所以我決定用neo4j的插件去做這件事情. neo4j沒有像數據庫trigger這樣的東西.但是可以用transacitonEventhanlder來實現. 這就有一些問題.

  • 缺乏資料, 可能因為我是python程序員的緣故,我對java和kotlin一知半解.
  • 事件並不是真的像他說的那樣運轉.比如beforeCommit.這個事件應該發生在數據庫未發生變化的時候,這個時候你應該是可以訪問被刪除的node.但是不是,你訪問不了.雖然該事務未提交. 幸好graphware提供了一系列的插件來支持這些事情.

總結

我沒有說Neo4j不能用於生產了,畢竟在它的官網那么多大公司都用了. 但是它至少還有待完善. 經過使用了半年之后.我就決定將數據從neo4j遷出. 只在neo4j中保留全部數據集的子集.用來做一些必要的圖搜索算法.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM