From 5ed96fac7990bc6d4bc1545c4de9f29b5af7a359 Mon Sep 17 00:00:00 2001 From: cooper-lzy <78672629+cooper-lzy@users.noreply.github.com> Date: Mon, 7 Mar 2022 14:23:32 +0800 Subject: [PATCH] Merge 3.0.0 (#1516) * Update 1.text-based-index-restrictions.md * Update 4.nebula-graph-crud.md * Update 2.find-path.md * Update 2.find-path.md * Add ranking config in exchange examples (#1407) * add license check (#1410) * Update 2.match.md * Update 2.match.md * Update nebula-plato.md (#1411) * Update 1.nebula-client.md * update start sh * update stop sh * update stop sh * change start service setting * update start * Update nebula-plato.md * Add ranking config in exchange examples (#1412) * timestamp_in_logfile_name and logrotate faq (#1400) * Fix exchange conf link (#1414) * Update note.css * Update 3.cluster-information.md * disable balance data (#1416) * update config shell * update nebula-dashboard server config * fix schema rule (#1418) * Update README.md * Update 2.deploy-dashboard.md * Add next step * Update mkdocs.yml (#1422) * Update 1.what-is-dashboard-ent.md * [WIP]update Studio (#1419) * [WIP]update Studio * update-0124 * Update st-ug-deploy.md * [wip] explore 216 --what is explorer & deployment updates (#1417) * [wip] explore 216 --what is explorer updates * explorer 216 -- deploy&connect * Update mkdocs.yml * Update mkdocs.yml * [WIP] explorer220-overview (#1421) * explorer220-overview * Update ex-ug-page-overview.md * Update st-ug-what-is-graph-studio.md * Explorer220 query (#1423) * explorer220-overview * explorer 220-query * Update st-ug-crud-tag.md * node-filtering (#1424) * dashboard ent config_file update (#1426) * dashboard ent config_file update * Update 2.deploy-connect-dashboard-ent.md * Create 2.deploy-connect-dashboard-ent.md * Update 1.insert-edge.md * Update 2.data-model.md * Update 2.graph-modeling.md * dashboard-ent-custom-installation path (#1430) * dashboard-ent-custom-installation path * Update 1.create-cluster.md * update-picture * Update 1.what-is-dashboard.md * [WIP] explorer 220 graph-exploration (#1429) * explorer 220 - canvas (#1433) * Update 2.deploy-dashboard.md * Update 2.deploy-dashboard.md * Update upgrade docs (#1427) * Update upgrade docs * Update upgrade docs * Update upgrade-nebula-from-200-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Resolve Whitewum's and Harris's comments * Fix some issues * update resource calculation * add caution for date_time_zonespec.csv * delete zone (#1434) * manage storage hosts (#1437) * manage storage hosts * update * Update manage-storage-host.md * Add faq for job id issue (#1438) * Remove zone (#1439) * Remove zone (#1440) * Remove zone * Update 4.nebula-graph-crud.md * Exchange support PostgreSQL data source (#1441) * [WIP] explorer220-updates (#1435) * explorer220-updates * updates * Update mkdocs.yml * console updates * Update canvas-overview.md * Update visualization-mode.md * Update visualization-mode.md * show hosts (#1442) * show hosts The `show hosts` command displays the version * Update 6.show-hosts.md * Update learning-path.md * Update 2.data-model.md * Update compaction.md * Update compaction.md * Update compaction.md * Update 3.system-design.md * Update 3.system-design.md * Update st-ug-release-note.md * Update nebula-bench.md * Update how-to-contribute.md * Update how-to-contribute.md * Update 6.eco-tool-version.md * Update 6.eco-tool-version.md * Update 0.FAQ.md * Create 0.FAQ.md (#1443) * Update use-importer.md * Update mkdocs.yml * Update 6.eco-tool-version.md * update clients (#1444) * Update 3.system-design.md * Update ex-ug-deploy.md (#1445) * Update ex-ug-graph-exploration.md * update docs (#1446) * Update ex-ug-graph-exploration.md * Update 6.kill-query.md (#1448) * Update 2.deploy-dashboard.md * Update ex-ug-shortcuts.md * Update ex-ug-graph-exploration.md (#1449) * Update st-ug-deploy-by-helm.md (#1450) * Update explorer-console.md (#1451) * Update source_connect-to-nebula-graph.md * Update 5.nebula-python-client.md (#1452) as we use format string in nebula-python, don't support python3.5 * update * Update 6.show-hosts.md * add gifs for dashboard 110 (#1453) * Update 6.pricing.md * Update 1.what-is-br.md * Update 4.storage-service.md * Update 2.deploy-dashboard.md (#1455) * Update 1.what-is-nebula-graph.md * Update mkdocs.yml (#1456) * Update 2.deploy-dashboard.md (#1457) * Update 2.deploy-dashboard.md * Dashboard community deploy&connect updates (#1460) * deploy&connect updates for dashboard community * Update mkdocs.yml * update release notes (#1459) * update release notes * update * update * update * Update releasenote.md * Update 2.deploy-dashboard.md * Update releasenote.md * Update releasenote.md * Update learning-path.md fix invalid video list url * Update deploy.yaml * Update visualization-mode.md (#1463) * Update ex-ug-compile.md * Update releasenote.md * Update releasenote.md * update br 0211 (#1461) * update br 0211 * update * add * Update 4.br-restore-data.md * Update 4.br-restore-data.md * Update 2.compile-br.md * Update 1.configurations.md * Update mkdocs.yml * Update mkdocs.yml * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * fixed some issues (#1467) * Update releasenote.md * Update 2.deploy-connect-dashboard-ent.md (#1468) * Update 4.describe-space.md * Update upgrade-nebula-graph-to-latest.md * Update releasenote.md * Create releasenote.md * Update releasenote.md * Update mkdocs.yml * update-br * Update 2.deploy-connect-dashboard-ent.md * update branch of client (#1469) * Update mkdocs.yml * Update 4.nebula-java-client.md * update compatibility (#1470) * Update 3.br-backup-data.md * Update 3.br-backup-data.md * Update nebula-plato.md * Update 3.br-backup-data.md * Update nebula-plato.md * Update st-ug-deploy.md * Update 3.br-backup-data.md * Update st-ug-deploy.md * Update 4.br-restore-data.md * Update 4.br-restore-data.md * Update 3.br-backup-data.md * Update st-ug-release-note.md * Update ex-ug-limitations.md * Update mkdocs.yml * Update use-importer.md * Update use-importer.md * Update nebula-algorithm.md * Update config-with-header.md * Update config-without-header.md * Update releasenote.md * Update st-ug-what-is-graph-studio.md * Update nebula-algorithm.md * Update nebula-spark-connector.md (#1473) * Update ex-ug-import-from-mysql.md * update exchange 3.0.0 (#1474) * [WIP]change plato name (#1472) * change plato name * update * Update nebula-analytics.md * Update nebula-analytics.md * Update 6.eco-tool-version.md * Update 3.system-design.md * Update nebula-analytics.md * Update releasenote.md * Update releasenote.md * add br * Update releasenote.md * Update releasenote.md * Update releasenote.md * Update releasenote.md * Update learning-path.md * Update learning-path.md * Update learning-path.md * Update learning-path.md (#1476) * Update nebula-console.md * Update nebula-console.md (#1477) * Update studio 3.2.1 (#1478) * Update 6.eco-tool-version.md (#1479) * Update logo.css (#1480) * Update 1.configurations.md (#1481) * Fix link and add cloud (#1482) * Update nebula-cloud.md * Update 6.eco-tool-version.md * Update 3.graph-service.md (#1483) * Update 3.graph-service.md * Update 3.alter-tag.md * Update 3.alter-tag.md * Update 3.alter-tag.md * commit id update and rm old pics (#1488) * Update 0.FAQ.md * Update 0.FAQ.md (#1489) * Update 1.overview.md (#1490) * Update 5.lookup.md * Update 1.create-native-index.md * Update 4.br-restore-data.md * Update 0.FAQ.md * note for basketallplayer (#1491) * note for basketallplayer * Update 1.overview.md * vm.min_free_kbytes is a setting of Linux Virtual Memory not Virtual Machine (#1493) as titled * Upgrade with no auto-backup (#1494) * Upgrade with no auto-backup The db-upgrader currently does not backup the old data. * Update upgrade-nebula-graph-to-latest.md * Update upgrade-nebula-graph-to-latest.md * Update 0.FAQ.md (#1495) * Update 0.FAQ.md * Create 0.FAQ.md * Update 0.FAQ.md (#1496) * Update 1.what-is-br.md * Update canvas-snapshot.md * Update manage-storage-host.md (#1497) * Update 8.faq.md (#1498) * Update 3.graph-service.md (#1499) * Update mkdocs.yml (#1500) * Create 6.eco-tool-version.md * Update st-ug-what-is-graph-studio.md * Update st-ug-terms.md * Update 6.eco-tool-version.md (#1501) * Update mkdocs.yml (#1502) * Update mkdocs.yml * Update mkdocs.yml * Explain storage format change (#1503) * Explain storage format change in 3.x * Update edge format * Update 4.storage-service.md * Update mkdocs.yml * Update requirements.txt * Update requirements.txt * Update nebula-analytics.md * Update mkdocs.yml * Update requirements.txt * Update mkdocs.yml * Synchronize book with 3.0.0 (#1504) * synchronize book with 3.0.0 * Update mkdocs.yml * Update history.md (#1505) * Update 1.what-is-br.md (#1506) * fixed create index comment syntax (#1507) ref: https://github.com/vesoft-inc/nebula/issues/3945 * Update nebula-analytics.md * fix analytics docs (#1508) * Update 2.match.md (#1509) * Update visualization-mode.md (#1510) * Update ex-ug-import-from-sst.md * Update ex-ug-import-from-clickhouse.md * Update ex-ug-import-from-csv.md * update full-text index (#1511) * Fix exchange config files (#1512) * Update write-tools.md * Update write-tools.md * Update 3.role-list.md * Update keywords-and-reserved-words.md (#1513) * Update keywords-and-reserved-words.md * Update keywords-and-reserved-words.md * fix some typos (#1515) * ADD HOSTS in docker deployment (#1514) This will prevent users from being confused. * Update deploy.yaml Co-authored-by: min.wu <50101159+whitewum@users.noreply.github.com> Co-authored-by: foesa <35463247+foesa-yang@users.noreply.github.com> Co-authored-by: randomJoe211 <69501902+randomJoe211@users.noreply.github.com> Co-authored-by: abby.huang <78209557+abby-cyber@users.noreply.github.com> Co-authored-by: li Nico <37568394+NicolaCage@users.noreply.github.com> Co-authored-by: Harris.Chu <1726587+HarrisChu@users.noreply.github.com> Co-authored-by: Steam Co-authored-by: Nut He <18328704+hetao92@users.noreply.github.com> Co-authored-by: jingchun.xia <6269380+xiajingchun@users.noreply.github.com> Co-authored-by: Wey Gu --- docs-2.0/1.introduction/0-0-graph.md | 230 ++++++++++++++++ docs-2.0/1.introduction/0-1-graph-database.md | 245 +++++++++++++++++ docs-2.0/1.introduction/0-2.relates.md | 251 ++++++++++++++++++ .../3.0-edge-key.png | Bin 0 -> 8574 bytes .../3.0-vertex-key.png | Bin 0 -> 16117 bytes .../3.graph-service.md | 6 +- .../4.storage-service.md | 60 ++--- .../edge-division.png | Bin 0 -> 67790 bytes docs-2.0/20.appendix/0.FAQ.md | 16 +- docs-2.0/20.appendix/6.eco-tool-version.md | 3 +- docs-2.0/20.appendix/history.md | 42 +++ docs-2.0/20.appendix/releasenote.md | 141 +++++++++- docs-2.0/20.appendix/write-tools.md | 4 +- .../1.nGQL-overview/1.overview.md | 7 +- .../keywords-and-reserved-words.md | 8 +- .../10.tag-statements/3.alter-tag.md | 5 +- .../1.create-native-index.md | 4 +- .../1.search-with-text-based-index.md | 2 +- .../3.ngql-guide/5.operators/2.boolean.md | 4 +- .../7.general-query-statements/2.match.md | 10 +- .../7.general-query-statements/5.lookup.md | 2 +- ...deploy-nebula-graph-with-docker-compose.md | 10 +- .../upgrade-nebula-graph-to-latest.md | 11 +- .../6.deploy-text-based-index/2.deploy-es.md | 4 +- .../manage-storage-host.md | 4 + .../1.configurations/6.kernel-config.md | 2 +- .../1.authentication/3.role-list.md | 6 +- docs-2.0/nebula-analytics.md | 2 +- docs-2.0/nebula-br/1.what-is-br.md | 7 + docs-2.0/nebula-br/4.br-restore-data.md | 2 +- docs-2.0/nebula-dashboard-ent/8.faq.md | 4 +- .../nebula-dashboard/2.deploy-dashboard.md | 4 +- .../ex-ug-import-from-clickhouse.md | 6 +- .../use-exchange/ex-ug-import-from-csv.md | 6 +- .../use-exchange/ex-ug-import-from-hbase.md | 6 +- .../use-exchange/ex-ug-import-from-hive.md | 6 +- .../use-exchange/ex-ug-import-from-json.md | 6 +- .../use-exchange/ex-ug-import-from-kafka.md | 6 +- .../ex-ug-import-from-maxcompute.md | 6 +- .../use-exchange/ex-ug-import-from-mysql.md | 6 +- .../use-exchange/ex-ug-import-from-neo4j.md | 4 +- .../use-exchange/ex-ug-import-from-orc.md | 6 +- .../use-exchange/ex-ug-import-from-parquet.md | 6 +- .../use-exchange/ex-ug-import-from-pulsar.md | 6 +- .../use-exchange/ex-ug-import-from-sst.md | 2 +- .../canvas-operations/canvas-snapshot.md | 2 +- .../canvas-operations/visualization-mode.md | 2 +- .../nebula-studio/about-studio/st-ug-terms.md | 2 + .../st-ug-what-is-graph-studio.md | 2 + .../reuse/source_connect-to-nebula-graph.md | 3 - docs-2.0/reuse/source_manage-service.md | 6 +- mkdocs.yml | 19 +- requirements.txt | 1 + 53 files changed, 1069 insertions(+), 136 deletions(-) create mode 100644 docs-2.0/1.introduction/0-0-graph.md create mode 100644 docs-2.0/1.introduction/0-1-graph-database.md create mode 100644 docs-2.0/1.introduction/0-2.relates.md create mode 100644 docs-2.0/1.introduction/3.nebula-graph-architecture/3.0-edge-key.png create mode 100644 docs-2.0/1.introduction/3.nebula-graph-architecture/3.0-vertex-key.png create mode 100644 docs-2.0/1.introduction/3.nebula-graph-architecture/edge-division.png create mode 100644 docs-2.0/20.appendix/history.md diff --git a/docs-2.0/1.introduction/0-0-graph.md b/docs-2.0/1.introduction/0-0-graph.md new file mode 100644 index 00000000000..153b6c1eecf --- /dev/null +++ b/docs-2.0/1.introduction/0-0-graph.md @@ -0,0 +1,230 @@ +# 图 + +当前,从计算机行业巨头(例如 Amazon 和 Facebook)到小型研究团队,都投入了大量的资源探索图数据库在解决各种数据关系问题上的潜力。当然你也可以选择像他们这样进行尝试,现在可供选择的数据库有很多。那么图数据库究竟是什么?它可以做些什么?作为一类数据库,它在数据库领域里处于什么位置呢?要回答这些问题,我们首先得了解图。 + +图是计算机科学研究的主要领域之一。图能够高效地解决目前存在的诸多问题。本章将从图说起,继而说明图数据库的优点及其在现代应用程序开发中的巨大潜力,然后介绍分布式图数据库的区别和几种其他类型的数据库。 + +## 图、图片与图论 + +图无处不在。当听到图这个词时,很多人都会想到条形图或折线图,因为有时候我们确实会把它们称作图。从传统意义上来说,图是用来展示两个或多个数据系统之间的联系的。最简单的例子如下图,下图展示了 Nebula Graph GitHub 仓库星星数量随时间推移的变化。 + +![image](https://user-images.githubusercontent.com/42762957/91426247-d3861000-e88e-11ea-8e17-e3d7d7069bd1.png "这不是本书所说的图") + +这是相对比较简单的一种图,横轴为时间,纵轴为星星数量。可以看到,星星数量是随着时间推移而上升的。这种类型的图通常称为折线图。折线图可以显示随时间(根据常用比例设置)而变化的连续数据。此处我们只给出了折线图的例子。当然图的形式有多种,比如饼图、条形图等。 + +还有一种“图”在日常口语中会更多的被提及,例如,“图像识别”,“美图秀”,“修图”等。例如下“图”的左边。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/image.png "这也不是本书所说的图") + +但是——总会有但是——我们在本书中讨论的图是另外一个概念——“图论”中的图。 + +在数学的分支图论中,图是基本研究对象,用于表示实体与实体之间的关系。一张图由一些小圆点(称为顶点或节点,即 Vertex)和连接这些圆点的直线或曲线(称为边,即 Edge)组成。“图(Graph)”这一名词最早由西尔维斯特在 1878 年提出。 + +通常,在英文中,为了区分这两种不同的图,前者会称为 Image,后者称为 Graph。在中文中,前者会强调为“图片”,后者会强调为“拓扑图”、“网络图”等。 + +![Image](https://docs-cdn.nebula-graph.com.cn/books/images/undirectedgraph.png) + + 这才是本书所说的图。 + +简单来说,图论就是研究图的学问。图论始于 18 世纪初期的柯尼斯堡七桥问题。柯尼斯堡当时是普鲁士的城市(现在属于俄罗斯,更名为加里宁格勒)。普雷格尔河穿过柯尼斯堡,不仅把柯尼斯堡分成了两部分,而且还在河中间形成了两个小岛。这就将整个城市分割成了四个区域,各区域由七座桥连接。当时有一个与柯尼斯堡相关的小游戏,即如何只穿过每座桥一次,浏览整个城市的四个区域。下图为柯尼斯堡七座桥的简化图。 有兴趣的话可以试试寻找这个小游戏的答案[^171]。 + +![image](https://user-images.githubusercontent.com/42762957/91536940-1526c180-e948-11ea-8fe8-90f40ce28171.png) + +[^171]: 图片来源 https://medium.freecodecamp.org/i-dont-understand-graph-theory-1c96572a1401. + +大数学家欧拉为了解决了这一问题。通过将城市的四个区域抽象成点,将连接城市的七座桥抽象成连接点的边,欧拉证明了这一问题是无法解决的。简化的抽象图如下[^063]: + +![image](https://user-images.githubusercontent.com/42762957/91538126-e578b900-e949-11ea-980c-5704254e8063.png) + +[^063]: 图片来源 https://medium.freecodecamp.org/i-dont-understand-graph-theory-1c96572a1401 + +图中四个点代表柯尼斯堡的四个区域,点之间的线代表连接四个区域的七座桥。从图中不难看出,偶数座桥连接的区域可以轻松通过,因为来去可以选择不同的路线。奇数座桥连接的区域只能作为起点或者终点,因为同样的路线只能走一次。和节点相关联的边的条数称为节点度。现在可以证明,只有两个节点有奇数度,另外节点有偶数度时,也即两个区域必须有偶数座桥,剩下的区域有奇数座桥时,柯尼斯堡问题才能解决。然而由上图得知,柯尼斯堡的任何区域都没有偶数座桥,所以这个谜题无解。 + +## 属性图 + +从数学角度来说,图论是研究建模对象之间关系结构的学科。但是从工业界使用的角度,通常会对基础的图模型进行扩展,称为**属性图模型**。属性图通常由以下几部分组成: + +- 节点,即对象或实体。在本书中,通常简称为点(Vertex)。 +- 节点之间的关系,在本书中,通常简称为边(Edge)。通常边是有方向或者无方向的,以表示两个实体之间有持续的关系。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/un-directed.png) + +- 此外,在节点和边上,还可以有属性(properties)。 + +在现实生活中,有很多属性图的例子。 + +例如企查查或者 BOSS 直聘这类的公司,用图来建模商业股权关系网络。这个网络中,点通常是一个自然人或者是一家企业,边通常是某自然人与某企业之间的股权关系。点上的属性可以是自然人姓名、年龄、身份证号等。边上的属性可以是投资金额、投资时间、董监高等职位关系。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/enterprise-relations.png) + +在一个股票市场里面,点可以是一家上市公司,边可以是上市公司之间的相关性。点的属性可以为股票代码、简称、市值、板块等;边的属性可以为股价的时间序列相关性系数[^T01]。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/JGraphT01.png) + +[^T01]: https://nebula-graph.com.cn/posts/stock-interrelation-analysis-jgrapht-nebula-graph/ + +图关系还可以是类似《权力的游戏》这样电视剧中的人物关系网[^s-01]:点为人物,边为人物之间的互动关系;点的属性为人物姓名、年龄、阵营等,边的属性(距离)为两个人物之间的互动次数,互动越频繁距离越近。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/game-of-thrones-01.png) + +[^s-01]: https://nebula-graph.com.cn/posts/game-of-thrones-relationship-networkx-gephi-nebula-graph/ + +图也可以用于 IT 系统内部的治理。例如,对于像微众银行这样的公司,通常有着非常庞大的数据仓库,以及相应的数仓管理工具。这些管理工具记录了数仓内 Hive 表之间通过 Job 实现的 ETL 关系[^ware],这样的 ETL 关系,可以非常方便的用图的形式呈现和管理,当出现问题时也可以非常方便地追溯根源。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/dataware.png) +![image](https://docs-cdn.nebula-graph.com.cn/books/images/dataware2.png) + +[^ware]: https://nebula-graph.com.cn/posts/practicing-nebula-graph-webank/ + +图也可以用于记录一个大型 IT 系统内部错综复杂的微服务之间的调用关系[^tice],运维团队用其进行服务治理。这里每个点表示一个微服务,边表示两个微服务之间的调用关系;这样,运维人员可以方便地寻找可用性低于阈值 (99.99%) 的调用链路,或者发现那些出故障会影响面特别大的微服务节点。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/microserve.png) + +图也可以用于提升代码开发效率。用图存放代码之间的函数调用关系[^tice],可以提升研发团队审查和测试代码的效率。在这样的图中,每个点是代码中的一个函数或者变量,每个边是函数或者变量之间的调用关系。当有新提交的代码之时,人们可以更方便的看到可能会受到影响到的其他接口,这样可以帮助测试人员更好的评估潜在的上线风险。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/code.png) + +[^tice]: https://nebula-graph.com.cn/posts/meituan-graph-database-platform-practice/ + +此外,相对于静态不发生变化的属性图,我们还可以通过增加一些时间信息,发掘出更多的使用场景。 + +例如,在一个银行间账户资金流向网络里面[^1440w],点是账户,边是账户之间的转账记录。边属性记录了转账的时间、金额等。同盾、邦盛、半云科技等公司采用图技术,可以方便地通过图的方式探索发现明显的资金挪用、“以贷还贷”、“团伙贷款”等现象。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/bank-transfer.jpg) + +[^1440w]: https://zhuanlan.zhihu.com/p/90635957 + +同样的方法也可以用于探索发现加密货币的流向。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/block-chain.png) + +在一个黑产账户和设备网络中[^360],其中的点可以是账户、手机设备和 WIFI 网络,边是这些账户与手机设备之间的登录关系,以及手机设备和 WIFI 网络之间的接入关系。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/360-user-1.png) + +这些登录记录的网络构成了黑产群体网络的团伙作案特征。360 数科[^360]、快手[^kuaishou]、微信[^weixin]、知乎[^zhihu]、携程金融这些公司都通过图技术实时(毫秒级的)识别超过百万个的黑产社群。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/360-user-2.png) + +[^360]: https://nebula-graph.com.cn/posts/graph-database-data-connections-insight/ + +[^kuaishou]: https://nebula-graph.com.cn/posts/kuaishou-security-intelligence-platform-with-nebula-graph/ + +[^weixin]: https://nebula-graph.com.cn/posts/nebula-graph-for-social-networking/ + +[^zhihu]: https://mp.weixin.qq.com/s/K2QinpR5Rplw1teHpHtf4w + +更进一步,除了时间这个维度外,我们通过添加一些地理位置信息,还能发现属性图更多的应用场景。 + +例如新冠病毒的流行病学溯源[^CoV02],点是人物,边是人与人之间的接触;点属性为人物的身份证、发病时间等信息,边属性为人物之间发生密切接触的时间和地理位置等。为卫生防疫部门快速识别高风险人群和其行为轨迹提供帮助。 + +![image](https://www-cdn.nebula-graph.com.cn/nebula-blog/nCoV02.png) + +[^CoV02]: https://nebula-graph.com.cn/posts/detect-corona-virus-spreading-with-graph-database/ + +地理位置与图的结合也可以用于一些 O2O 的场景,例如基于 POI(Point-of-Interest)的实时美食推荐[^mt],使得美团这类本地生活服务平台公司能在消费者在打开 APP 的时候,实时推荐出更为合适的商家。 + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/meituan2.png) + +![image](https://docs-cdn.nebula-graph.com.cn/books/images/meituan.png) + +[^mt]: https://nebula-graph.com.cn/posts/meituan-graph-database-platform-practice/ + +图还可以用于更深度的知识推理,华为、vivo、OPPO、微信、美团等公司,将图用于表征底层知识关系的数据模型。 + +## 为什么要使用图数据库 + +虽然关系型数据库与 XML/JSON 等半结构类型的数据库,都可以用来描述图结构的数据模型,但是,图(数据库)不仅可以描述图结构与存储数据本身,更着眼于处理数据之间的关联(拓扑)关系。具体来说,图(数据库)有这么几个优点: + +- 图是一种更直观、更符合人脑思考直觉的知识表示方式。这使得我们在抽象业务问题时,可以着眼于“业务问题本身”,而不是“如何将问题描述为数据库的某种特定结构(例如表格结构)”。 + +- 图更容易展现数据的特征,例如转账的路径、近邻的社区。例如,如果要分析《权力的游戏》中的人物派别关系和人物重要性,表的组织方式如下: + + ![image](https://www-cdn.nebula-graph.com.cn/nebula-blog/gephi-01.jpeg) + + 这显然不如下方图的组织方式直观: + + ![image](https://www-cdn.nebula-graph.com.cn/nebula-blog/game-of-thrones-01.png) + + 特别是当某些中心节点被删除: + + ![image](https://www-cdn.nebula-graph.com.cn/nebula-blog/tv-game-thrones.png) + + 或者,增加一条边,可以彻底地改变整个图拓扑: + + ![image](https://www-cdn.nebula-graph.com.cn/nebula-blog/tv-game-thrones-02.png) + + 虽然只是个别数据的细微改变,图可以比表更直观地表现其中的重要而系统的信息。 + +- 图查询语言是针对图结构访问设计的,可以更加直观。例如,下面是一个 LDBC 中的查询示例,要求:查找某人(Person)在社交网络上发布的帖子(Posts);查找相应的回复(Message,回复本身还会被多次回复);发帖时间、回帖时间都满足一定条件;根据回帖数量对结果排序。 + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/efficientquery.png) + + 如果使用 PostgreSQL 编写查询语句: + + ```SQL + --PostgreSQL + WITH RECURSIVE post_all(psa_threadid + , psa_thread_creatorid, psa_messageid + , psa_creationdate, psa_messagetype + ) AS ( + SELECT m_messageid AS psa_threadid + , m_creatorid AS psa_thread_creatorid + , m_messageid AS psa_messageid + , m_creationdate, 'Post' + FROM message + WHERE 1=1 AND m_c_replyof IS NULL -- post, not comment + AND m_creationdate BETWEEN :startDate AND :endDate + UNION ALL + SELECT psa.psa_threadid AS psa_threadid + , psa.psa_thread_creatorid AS psa_thread_creatorid + , m_messageid, m_creationdate, 'Comment' + FROM message p, post_all psa + WHERE 1=1 AND p.m_c_replyof = psa.psa_messageid + AND m_creationdate BETWEEN :startDate AND :endDate + ) + SELECT p.p_personid AS "person.id" + , p.p_firstname AS "person.firstName" + , p.p_lastname AS "person.lastName" + , count(DISTINCT psa.psa_threadid) AS threadCount + END) AS messageCount + , count(DISTINCT psa.psa_messageid) AS messageCount + FROM person p left join post_all psa on ( + 1=1 AND p.p_personid = psa.psa_thread_creatorid + AND psa_creationdate BETWEEN :startDate AND :endDate + ) + GROUP BY p.p_personid, p.p_firstname, p.p_lastname + ORDER BY messageCount DESC, p.p_personid + LIMIT 100; + ``` + + 如果使用为图专门设计的图语言 Cypher 编写查询语句: + + ```Cypher + --Cypher + MATCH (person:Person)<-[:HAS_CREATOR]-(post:Post)<-[:REPLY_OF*0..]-(reply:Message) + WHERE post.creationDate >= $startDate AND post.creationDate <= $endDate + AND reply.creationDate >= $startDate AND reply.creationDate <= $endDate + RETURN + person.id, person.firstName, person.lastName, count(DISTINCT post) AS threadCount, + count(DISTINCT reply) AS messageCount + ORDER BY + messageCount DESC, person.id ASC + LIMIT 100 + ``` + +- 由于存储引擎和查询引擎可以针对图的结构专门设计,图的遍历(对应 SQL 中的 join)要高效得多。下图是知名产品 Neo4j 所做的一个对比[^mt]。 + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/neo4jhop.png) + +- 图数据库具有广泛的适用场景。例如数据集成(知识图谱)、个性化推荐、欺诈与威胁检测、风险分析与合规、身份(与控制权)验证、IT 基础设施管理、供应链与物流、社交网络研究等。 + +- 根据文献[^Ubiquity] 的统计,使用图技术最多的领域,依次是:信息技术(IT)、学术界研究、金融、工业界实验室、政府、医疗健康、国防、制药业、零售与电子商务、交通运输、电信、保险。 + +[^Ubiquity]: https://arxiv.org/abs/1709.03188 + +- 2019 年,根据 Gartner 的问卷调研,27% 的客户(500 组)在使用图数据库,20% 有计划使用。 + +## RDF + +受篇幅所限,本章不讨论 RDF 数据模型。 diff --git a/docs-2.0/1.introduction/0-1-graph-database.md b/docs-2.0/1.introduction/0-1-graph-database.md new file mode 100644 index 00000000000..e6942c40c94 --- /dev/null +++ b/docs-2.0/1.introduction/0-1-graph-database.md @@ -0,0 +1,245 @@ +# 图数据库的市场概况 + +既然已经讨论了什么是图,接下来让我们进一步认识基于图论和属性图模型发展起来的图数据库。 + +不同的图数据库在术语方面可能会略有不同,但是归根结底都是在讲点、边和属性。至于更多的功能,例如标签、索引、约束、TTL、长任务、存储过程和UDF等这些高级功能,在不同图数据库中,会存在明显的差异。 + +图数据库用图来存储数据,而图是最接近高度灵活、高性能的数据结构之一。图数据库是一种专门用于存储和检索庞大信息网的存储引擎,它能够高效地将数据存储为点和边,并允许对这些点边结构进行高性能的检索和查询。我们也可以为这些点和边添加属性。 + +图数据库几乎适用于存储所有领域的数据。因为在几乎所有领域中,事物之间都是由某种相关联的。图数据库支持存储实体之间的丰富关系,并且能够将这些关系完美地呈现出来,而无需像其他建模方式那样,将关系也当成实体存储。因此图数据库能够以最接近对数据直观认知的形式存储数据。 + +## 三方机构的统计和预测 + +### DB-Engines 的统计 + +根据世界知名的数据库排名网站DB-Engines.com的统计,图数据库至2013年以来,一直是“增速最快”的数据库类别[^dbe]。 + +该网站根据一些指标来统计每种类别的数据库的流行度变化趋势,这些指标包括基于Google等搜索引擎的收录和趋势情况、主要IT技术论坛和社交网站上讨论的技术话题、招聘网站的职位变化等。该网站共收录了371种数据库产品,并分为12个类别。这12个类别中,图数据库这种类别的增速远远快于其他任何的类别。 + +![Image](https://docs-cdn.nebula-graph.com.cn/books/images/db-rankings.png) + +[^dbe]: https://db-engines.com/en/ranking_categories + +### Gartner 的预测 + +世界顶级智库Gartner早在2013年之前[^Gartner1],就将图数据库作为主要的"商业智能与分析技术趋势"。在那个时候,Big Data正火热的如日中天,数据科学家更是炙手可热的职位。 + +![Image](https://docs-cdn.nebula-graph.com.cn/books/images/gartner.jpg) + +[^Gartner1]: https://www.yellowfinbi.com/blog/2014/06/yfcommunitynews-big-data-analytics-the-need-for-pragmatism-tangible-benefits-and-real-world-case-165305 + +直到最近,图数据库及相关的图技术依旧是"2021年十大数据与分析趋势"[^Gartner2]: + +![Image](https://images-cdn.newscred.com/Zz01NWM5ZDE3YzcxM2UxMWViODBhMDE5NTExMjNjOTZmZQ==) + +!!! quote "趋势八:图技术使一切产生关联(Graph Relates Everything)" + + 图技术已成为许多现代数据和分析能力的基础,能够在不同的数据资产中发现人、地点、事物、事件和位置之间的关系。数据和分析领导者依靠图技术快速回答需要在了解情况并理解多个实体之间的联系和优势的性质后才能回答的复杂业务问题。 + + Gartner预测,到2025年图技术在数据和分析创新中的占比将从2021年的10%上升到80%。该技术将促进整个企业机构的快速决策。 + +[^Gartner2]: https://www.gartner.com/smarterwithgartner/gartner-top-10-data-and-analytics-trends-for-2021/ + +可以注意到,Gartner 的预测比较好的吻合了 DB-Engines 的统计结论。技术的进步并不是完全线性的,通常会有一段快速发展的泡沫期,然后进入一段平台期,之后由于新的技术的出现产生新一轮的泡沫期,再经历一段平台期。以此往复螺旋形的循环发展。 + +### 对于市场规模的预测 + +根据 verifiedmarketresearc[^ver], fnfresearch[^fnf], marketsandmarkets[^mam], 以及 gartner[^gar] 等智库的统计和预测,图数据库市场(包括云服务)规模在2019年大约是8亿美元,将在未来6年保持25%左右的年复合增长(CAGR)至 30-40 亿美元,这大约对应于全球数据库市场 5-10% 的市场份额。 + +![Image](https://www.verifiedmarketresearch.com/wp-content/uploads/2020/10/Graph-Database-Market-Size.jpg) + +[^ver]: https://www.verifiedmarketresearch.com/product/graph-database-market/ + +[^fnf]: https://www.globenewswire.com/news-release/2021/01/28/2165742/0/en/Global-Graph-Database-Market-Size-Share-to-Exceed-USD-4-500-Million-By-2026-Facts-Factors.html + +[^mam]: +https://www.marketsandmarkets.com/Market-Reports/graph-database-market-126230231.html + +[^gar]: https://www.gartner.com/en/newsroom/press-releases/2019-07-01-gartner-says-the-future-of-the-database-market-is-the + +## 市场参与者 + +### (第一代)图数据库的先行者 Neo4j + +虽然在 1970 年代,人们已经提出了一些类似于"图”的数据模型和产品原型(例如 CODASYL[^DDIA])和相应的图语言 G/G+ 语言[^Glang]。但真正能够让“图数据库”这个概念流行起来,不得不说到这个市场最主要的先行者 Neo4j,甚至(标签)属性图和图数据库这两个主要术语就是 Neo4j 最早提出并实践的。 + +[^DDIA]: https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321 + +[^Glang]: I. F. Cruz, A. O. Mendelzon, and P. T. Wood. A Graphical Query Language Supporting Recursion. In Proceedings of the Association for Computing Machinery Special Interest Group on Management of Data, pages 323–330. ACM Press, May 1987. + + +!!! Info "本小节关于Neo4j和其创造的图查询语言Cypher的历史内容主要摘录自 ISO WG3 的工作论文"An overview of the recent history of Graph Query Languages"[^Tobias2018] 和[^Glang],本书作者根据最新两年的进展有删减和更新。" + +!!! Note "关于图查询语言(Graph Query Language,GQL) 和国际标准的制定" + + 熟悉数据库的读者可能都知道结构化查询语言SQL。通过使用SQL,人们以接近自然语言的方式访问数据库。在 SQL 被广泛采用和标准化之前,关系型数据库的市场是非常碎片和割裂的——各家厂商的产品都有完全不同的接入访问方式,数据库产品自身的开发人员、数据库产品周边工具的开发人员、数据库最终的使用人员,都不得不学习各个厂商的完全不同的产品,在不同产品之间迁移极其困难。当1989年SQL-89标准被制定后,整个关系型数据库的市场快速收敛到SQL-89上。这大大降低了上述各种人员的学习曲线。 + + 类似的,在图数据库领域,图语言(GQL)承担了类似于SQL的作用,是一种用户与图数据库主要的交互方式。但不同于SQL-89这种国际标准,GQL还没有任何国际标准。目前有两种主流的图语言: + + Neo4j的Cypher (及其后续——ISO正在制定过程中的 GQL-standard 草案)和Apache TinkerPop的Gremlin。前者通常被称为声明式语言(Declarative query language)——也即用户只需要告诉系统“要什么”,而不管“怎么做”;后者通常被称为命令式语言(Imperative query language),用户会显式地指定系统的操作。 + + GQL国际标准正在制定过程中。 + +[^Tobias2018]: "An overview of the recent history of Graph Query Languages". Authors: Tobias Lindaaker, U.S. National Expert.Date: 2018-05-14 + +#### 年表简述 + +- 2000 年,Neo4j 的创始人产生将数据建模成网络(network)的想法。 +- 2001 年,Neo4j 开发了最早的核心部分代码。 +- 2007 年,Neo4j 开始以一个公司的方式运作。 +- 2009 年,Neo4j 团队借鉴 XPath 作为图查询语言,Gremlin[^Gremlin]最初也是基于这个想法。 +- 2010 年,Neo4j 的员工 Marko Rodriguez 采用术语属性图(Property Graph)来描述 Neo4j 和 Tinkerpop / Gremlin 的数据模型。 +- 2011 年,第一个公开发行版本 Neo4j 1.4; 并发布了Cypher的第一个版本。 +- 2012 年,Neo4j 1.8 为 Cypher 增加写入图的能力。Neo4j 2.0 增加了标签和索引,Cypher 成为一种声明式的语言。 +- 2015 年,Neo4j 将 Cypher 开源为 openCypher。 +- 2017 年,ISO WG3 工作组开始讨论如何将属性图查询能力引入 SQL。 +- 2018 年 12 月,从 Neo4j 3.5 开始其核心部分转为闭源。 +- 2019 年, ISO 正式立项两个项目(ISO/IEC JTC 1 N 14279和ISO/IEC JTC 1/SC 32 N 3228),启动关于图数据库语言国际标准的制定工作。 +- 2021 年,Neo4j 完成 F 轮 3.25 亿美元的融资,是整个数据库(包括关系型)历史上最大一轮融资。 + +[^Gremlin]: Gremlin是基于Apache TinkerPop开发的图语言(https://tinkerpop.apache.org/)。 + +#### Neo4j 的早期历史 + +Neo4j 和属性图这种数据模型,最早构想于 2000 年。Neo4j 的创始人们当时在开发一个媒体管理系统,所使用的数据库的 schema 经常会发生重大变化。为了支持这种灵活性,Neo4j 的联合创始人 Peter Neubauer,受到 Informix Cocoon 的启发,希望将系统能够建模为一种概念相互连接的网络。印度理工学院孟买分校的一群研究生们实现了最早的原型。Neo4j 的联合创始人 Emil Eifrém 和这些学生们花了一周的时间,将 Peter 最初的想法扩展成为一个更抽象的模型:节点通过关系连接,key-value 作为节点和关系的属性。这群人开发了一个 Java API 来和这种数据模型交互,并在关系型数据库之上实现了一个抽象层。 + +虽然这种网络模型极大的提高了生产力,但是性能一直很差。所以 Neo4j 联合创始人 Johan Svensson 花了不少精力,为这种网络模型实现了一个原生的数据管理系统。这个就成为了 Neo4j。在最初的几年,Neo4j 作为一个内部产品很成功。在 2007 年,Neo4j 的知识产权转移给了一家独立的数据库公司。 + +在 Neo4j 的第一个公开发行版中(Neo4j 1.4,2011 年),数据模型由节点和有类型的边构成,节点和边都有 key-value 组成的属性。Neo4j 的早期版本没有任何的索引,应用程序只能从根节点开始自己构造查询结构(search structure)。因为这样对于应用程序非常笨重,Neo4j 2.0(2013.12)引入了一个新概念——点上的标签(label)。基于点标签,Neo4j 可以为一些预定义的节点属性建立索引。 + +"节点"、"关系"、"属性"、"关系只能有一个标签"、"节点可以有零个或者多个标签",以上这些概念构成了 Neo4j 属性图的数据模型定义。随着后来增加的索引功能,让 Cypher 成为了与 Neo4j 交互的主要方式。因为这样应用程序开发者只需要关注于数据本身,而不是上段提到的那个开发者自己构建的查询结构(search structure)。 + +#### Gremlin 的创造 + +Gremlin是基于Apache TinkerPop开发的图语言,其风格接近于一连串的函数(过程)调用。最初 Neo4j 的查询方式是通过 Java API。应用程序可以将查询引擎作为库(library)嵌入到应用程序中,然后使用 API 来查询图。 + +就在这段时间,NOSQL 这个概念开始出现。NOSQL 型的数据库引擎一般用 REST 和 HTTP 来交互和查询。Neo4j 的早期员工 Tobias Lindaaker、Ivarsson、Peter Neubauer 、Marko Rodriguez用 XPath 作为图查询,Groovy 提供循环结构,分支和计算(等图灵完毕的功能)。 这个就是 Gremlin 最初的原型。 2009 年 11 月发布了第一个版本。 + +后来,Marko 发现同时用两种不同的解析器(XPath 和 Groovy)有很多问题,就将 Gremlin 改为基于 Groovy 的一种领域特定语言(DSL)。 + +#### Cypher 的创造 + +Gremlin 和 Neo4j 的 Java API 一样,最初用于表达如何查询数据库的一种过程(Procedural)。它允许更短的语法来表达查询,也允许通过网络远程访问数据库。Gremlin 这种过程式的特性,需要用户知道如何采用最好的办法查询结果,这样对于应用程序开发人员来说仍旧有负担。与此同时,在过去30年中,声明式语言 SQL 取得了极大的成功:SQL 可以将“获取数据的声明方式”和“引擎如何获取数据”相分开,所以 Neo4j 的工程师们希望开发一种声明式的图查询语言。 + +2010 年,Andrés Taylor 作为工程师加入 Neo4j。受 SQL 启发,他启动了一个项目来开发图查询语言,而这种新语言于 2011 年 Neo4j 1.4 发布,这种新语言就是如今大多数图查询语言的先祖——Cypher 。 + +Cypher 的语法基础,是用 "ASCII艺术(ASCII art)" 来描述图模式。这种方式最初来源于 Neo4j 工程师团队在源代码中评注如何描述图模式。可以看下图的例子: + +![Image](https://www-cdn.nebula-graph.com.cn/nebula-blog/the-origin-of-cypher.png) + +ASCII art 简单说,就是如何用可打印文本来描述点和边。Cypher 文本用`()`表示点,`-[]->`表示边。`(query)-[modeled as]->(drawing)` 来表示`起点 query`,`终点 drawing`,`边 modeled as`,这样一个最简单的图关系(也可以称为图模式)。 + +Cypher 第一个版本实现了对图的读取,但是需要用户说明从哪些节点开始查询。只有从这些节点开始,才可以支持图的模式匹配。 + +在后面的版本,2012 年 10 月发布的 Neo4j 1.8 中,Cypher 增加了修改图的能力。但查询还是需要指明从哪些节点开始。 + +2013 年 12 月,Neo4j 2.0 引入了 label 的概念,label 本质上是个索引。这样,查询引擎就可以利用索引,来选择模式所匹配到的节点,而不需要用户指定开始查询的节点。 + +随着 Neo4j 的普及,Cypher 有着广泛的开发者群体,在各行各业的得到广泛的使用。至今仍是最受欢迎的图查询语言。 + +2015 年 9 月,Neo4j 发起成立了 openCypher Implementors Group(oCIG),将 Cypher 开放为 openCypher,通过开源的方式来治理和推进语言自身的演化。 + +#### 后续 + +Cypher 启发了一系列后续的图查询语言,包括 + +2015 年,Oracle 发布图引擎PGX使用的图语言PGQL。 + +2016 年,Linked Data Benchmarking Council, LDBC 是一个行业知名的图性能基准评测机构。LDBC 发布 G-CORE + +2018 年,基于 Redis 的图库(library) RedisGraph 采用 Cypher 作为其图语言 + +2019 年,国际标准组织 ISO 启动两个项目,基于 openCypher, PGQL, GSQL[^GSQL], and G-CORE 等现有业界成果,启动图语言国际标准的制定过程 + +[^GSQL]: https://docs.tigergraph.com/dev/gsql-ref + +2019 年,Nebula Graph 以 openCypher 为基础发布其扩展的图语言 Nebula Graph Query Language, nGQL。 + +![Image](https://docs-cdn.nebula-graph.com.cn/books/images/langhis.jpg "图语言的历史") + +### 分布式图数据库 + +大约 2005-2010 年,随着 Google 云计算"三驾马车"的发布,各种分布式的架构开始越来越流行,其中就包括以开源方式运作的 Hadoop 和 Cassandra 等。这里包括几个方面的影响: + +1. 由于数据量和计算量越来越大,相比于单机(例如 Neo4j)或者小型机这种方案,分布式系统的技术和成本优势更加明显;而同时,分布式系统使得应用程序在访问这成千上万台机器时,就如同访问本地的系统一样,不需要在代码层面进行过多改造; + +2. 开源方式使得更多的人(包括代码开发者、数据科学家、产品经理等)以更加低成本和有效的方式参与新兴的技术,并反馈给社区。 + +严格说,Neo4j 也提供了不少的分布式的能力,但都和业界意义上的(对等、分片的)分布式系统有较大的不同: + +- Neo4j 3.X 要求全量数据必须存放在单机中。虽然其也提供多机之间(Master-slave/slave)做全量复制和高可用,但数据不可切分为不同子图存放。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/causal.png) + +- Neo4j 4.X 允许在不同机器上各存放一部分数据(子图),然后在应用层需通过一定方式拼装后(其称为编织 Fabric)[^fosdem20],将读写分发到各个机器上。这种做法需要应用层代码有大量的参与和工作。例如,设计如何把不同子图应该放置在哪些机器上,如何将从各机器获取的部分结果重新编织为最终的结果。 + +![](https://dist.neo4j.com/wp-content/uploads/20200131191103/Neo4j-Fabric-LDBC-sharding-scheme.jpg) + +[^fosdem20]: https://neo4j.com/fosdem20/ + +其语法风格大体是 +```Cypher +USE graphA # S1.1 从 Shard A 读 +MATCH (movie:Movie) +Return movie.title AS title + UNION # S2. 在代理服务器 Join 结果 +USE graphB # S1.2 从 Shard B 读 +MATCH (move:Movie) +RETURN movie.title AS title +``` + +![](https://docs-cdn.nebula-graph.com.cn/books/images/fabric.png) + +#### 第二代(分布式)图数据库:Titan 和其后继者 JanusGraph + +2011 年,Aurelius 公司成立,致力于开发一个开源的分布式图数据库 Titan[^titan]。到 2015 年 Titan 的第一个正式版发布,Titan 后端可以支持多种主流的分布式存储架构(例如 Cassandra, HBase, Elasticsearch, BerkeleyDB),并可以复用 Hadoop 生态的诸多便利,前端以 Gremlin 为统一的查询语言。对于程序员使用、开发和社区参与都很方便。大规模的图,可以分片后存放在 HBase 或者 Cassarndar上(这些当时都已经是相对成熟的分布式存储方案),Gremlin 语言虽然略微冗长但相对功能完备。整个方案在当时(2011-2015)体现了不错的竞争力。 + +[^titan]: https://github.com/thinkaurelius/titan + +下图显示了 2012年 - 2015 年,Titan 和 Neo4j 在 GitHub.com 上 star 的增长情况。 + +![Image](https://docs-cdn.nebula-graph.com.cn/books/images/titan-2015-neo4j.png) + +2015 年 Aurelius(Titan) 被 DataStax 收购,这之后 Titan 逐渐转变为一个闭源的商业产品 (DataStax Enterprise Graph)。 + +在 Aurelius(Titan) 被收购后,市场对于开源分布式的图数据库一直仍有比较强烈的需求,而当时市场上成熟和活跃的产品并不多。大数据时代,数据仍在远快于摩尔定律的速度,源源不断的产生。Linux 基金会以及一些技术巨头(Expero, Google, GRAKN.AI, Hortonworks, IBM and Amazon) 在2017年,复制并分叉(fork)了原有的Titan项目,并启动为一个新项目 JanusGraph[^Janus]。之后大多数的社区工作,包括开发、测试、发布和推广都逐步转移到了新的 JanusGraph。 + +[^Janus]: https://github.com/JanusGraph/janusgraph + +下图显示了两个项目2012-2021年日常代码提交(pull request)的变化情况,可以观察到几点: + +1. 即使 Aurelius(Titan) 2015 年被收购后,其开源代码仍有一定的活跃度(左侧),但增速已经明显放缓。这体现了社区的力量。 + +2. 新项目 JanusGraph 项目在 2017 年 1 月启动后,其社区迅速活跃起来,短短一年时间就超越了 Titan 过去 5 年累计的 pull request 数量。而与此同时,Titan 开源项目就此停滞。 + +![Image](https://docs-cdn.nebula-graph.com.cn/books/images/titan-janus-dev.png) + +#### 同期知名产品 OrientDB, TigerGraph, ArangoDB, 和 DGraph + +此后更多的厂商加入整个市场,除了由Linux基金会托管的 JanusGraph,还有一些由商业公司主导开发的分布式图数据,各方采用的数据模型和访问方式也有明显的不同。 +本文不做一一介绍,仅简单列出主要区别。 + +| 厂商名 | 创立时间 | 核心产品名 | 开源协议 | 数据模型 | 查询语言 | +| ----- | ----- | ----- | ----- | ----- | ----- | +| OrientDB LTD (2017 年 被 SAP 收购) | 2011 | OrientDB | 开源 | 文档 + KV + 图 | OrientDB SQL (基于SQL扩展的图能力) | +| GraphSQL (后改名 TigerGraph) | 2012 | TigerGraph | 商业版本 | 图(分析) | GraphSQL (类SQL风格) | +| ArangoDB GmbH | 2014 | ArangoDB | Apache License 2.0 | 文档 + KV + 图 | AQL (同时操作文档, KV 和图) | +| DGraph Labs | 2016 | DGraph | Apache Public License 2.0 + Dgraph Community License | 原 RDF,后改为 GraphQL | GraphQL+- | + +#### 传统巨头微软、亚马逊和甲骨文纷纷入场 + +除了聚焦于图产品的厂商外,传统巨头也纷纷进入这个领域。 + +Microsoft Azure Cosmos DB[^cosmos] 是一个在微软云上的多模数据库云服务,可以提供SQL、文档、图、key-value等多种能力; +Amazon AWS Neptune[^neptune] 是一种由 AWS 提供图数据库云服务, 可以提供属性图和 RDF 两种数据模型; +Oracle graph[^Oracle] 是关系型数据库巨头 Oracle 在图技术与图数据库方向的产品。 + +[^cosmos]: https://azure.microsoft.com/en-us/free/cosmos-db/ + +[^neptune]: https://aws.amazon.com/cn/neptune/ + +[^Oracle]: https://www.oracle.com/database/graph/ + +#### 新一代开源分布式图数据库 Nebula Graph + +在下一章,我们将正式介绍新一代开源分布式图数据库 Nebula Graph。 diff --git a/docs-2.0/1.introduction/0-2.relates.md b/docs-2.0/1.introduction/0-2.relates.md new file mode 100644 index 00000000000..78b22e4a91a --- /dev/null +++ b/docs-2.0/1.introduction/0-2.relates.md @@ -0,0 +1,251 @@ +# 相关技术 + +本节主要介绍两个和分布式图数据库关系密切的领域,数据库方面和图技术方面。 + +## 数据库方面 + +### 关系型数据库 + +关系型数据库,是指采用了关系模型来组织数据的数据库。关系模型为二维表格模型,一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。说到关系型数据库,大多数人都会想到 MySQL。MySQL 是目前最流行的数据库管理系统之一,支持使用最常见的结构化查询语言(SQL)进行数据库操作,并以表格、行、列的形式存储数据。这种存储数据的方法源自埃德加·科德(Edgar Frank Codd)于 1970 年提出的关系型数据模型。 + +在关系型数据库中,可以为待存储的每种类型的数据创建一个表。例如,球员表用来存储所有的球员信息,球队表用来存储球队信息等。SQL 表中的每行数据都必须包含一个主键(primary key)。主键是该行数据的唯一标识符。一般地,主键作为字段 ID 都是随行数自增的。关系型数据库自问世以来一直为计算机行业提供着非常好的服务,并将未来很长的时间内继续服务下去。 + +如果你用过 Excel、WPS 或其他类似的应用,你就会大概了解到关系数据库是如何工作的。首先设置好列,然后在对应的列下添加行数据。你可以对某一列数据进行求平均值或其他聚合操作,这与在关系型数据库 MySQL 中求平均值的操作类似。而 EXcel 中的数据透视表则相当于在关系型数据库 MySQL 中使用聚合函数和 CASE 语句对数据进行查询。一个 EXcel 文件可以有多张表,一张表就相当于 MySQL 的一张表。一个 EXcel 文件则类似于一个 MySQL 数据库。 + +#### 关系型数据库中的关系 + +与图数据库不同,关系型数据库(或 SQL 型的数据库)中的边也是作为实体存储在专门的边表中的。先创建两个表,球员(player)和球队(team),然后再创建表 player_team 作为边表。边表通常由相关的表 join 而成。例如,此处的边表 player_team 就由球员表和球队表 join 而成。 + +![image](https://user-images.githubusercontent.com/42762957/91702816-dc872200-ebab-11ea-8b36-577c29a3fe7a.png) + +这种存储边的方式在关联小型数据集时问题并不大,但是当关系型数据库中的关系太多时,问题就出现了。事实上,关系型数据库是非常“反关系的”。具体来说,当你只想查询一个球员的队友时,你必须对表中的所有数据进行 join 操作,然后再过滤掉你不需要的所有数据,当你的数据集达到一定规模时,这将给关系型数据库带来巨大压力。如果你想关联多张不同的表,可能在 join 爆炸(join bombs)前系统就已经无法响应了。 + +#### 关系型数据库起源 + +上文提到,关系型数据模型最早是由 IBM 的工程师埃德加·科德(Edgar Frank Codd)于 1970 年提出的。科德写了几篇数据库管理系统方面的论文,论述了关系型数据模型的潜力。关系型数据模型不依赖于数据链接列表(网状数据或层级数据),而是更多依赖于数据集。他使用元组演算(tuple calculus)的数学方法论证了这些数据集能够完成与导航数据库管理系统相同的任务。唯一的要求是,关系型数据模型需要一种合适的查询语言,以保证数据库的一致性要求。这就为后来声明型的结构化查询语言(SQL)提供了灵感来源。IBM 的 R 系统是关系型数据模型的最早使用者之一。然而,由前 IBM 员工拉里·埃里森创办的名叫软件开发实验室的小公司在市场上击败了 IBM。该公司的产品就是后来为我们熟知的 Oracle。 + +由于“关系数据库”在当时是一个比较时髦的词汇,因此许多数据库供应商都喜欢在其产品名称中使用这个词汇,尽管他们的产品实际上并不是关系型的。为了防止这种情况并减少关系型数据模型的错误使用,科德提出了著名科德 12 定律(Codd's 12 rules)。所有关系型数据系统都必须遵循科德 12 定律。 + +### NoSQL 数据库 + +图数据库并不是可以克服关系型数据库缺点的唯一替代方案。现在市面上还有很多非关系型数据库的产品,这些产品都可以叫做 NoSQL。NoSQL 一词最早于上世纪 90 年代末提出,可以解释为“非 SQL” 或“不仅是 SQL”,具体解释要根据语境判断。为便于理解,这里 NoSQL 可以解释成 “非关系型数据库”。不同于关系型数据库,NoSQL 数据库提供的数据存储、检索机制并不是基于表关系建模的。 NoSQL 数据库可以分为四类: + +- 键值存储(key-value stores) +- 列式存储(column-family stores) +- 文件存储(document stores) +- 图数据库(graph databases) + +下面将分别介绍这四类数据库。 + +#### 键值存储 + +键值存储,顾名思义,就是使用键值对存储数据的数据库。不同于关系型数据库,键值存储是没有表和列的。如果一定要做类比,键值数据库本身就像一张有很多列(也就是键)的大表。在键值存储数据库中,数据(即键值对中的值)都是通过键来存储和查询的,通常用哈希列表来实现。这比传统的 SQL 数据库要简单得多,而且对于某些 web 应用来说,这就足够了。 + +键值模型对于 IT 系统来说优势在于简单、易部署。多数情况下,这种存储方式对非关联的数据很适用。如是只是存储数据而无需查询的话,使用这种存储方法就没有问题。但是如果 DBA 只对部分值进行查询或更新的时候,键值模型就显得效率低下了。常见的键值存储数据库有:Redis、Voldemort、Oracle BDB。 + +#### 列式存储 + +NoSQL 数据库的列式存储与 NoSQL 数据库的键值存储有许多相似之处,因为列式存储仍然在使用键进行存储和检索。区别在于列式存储数据库中,列是最小的存储单元,每一列均由键、值以及用于版本控制和冲突解决的时间戳组成。这在分布式扩展时特别有用,因为在数据库更新时,可以使用时间戳定位过期数据。由于列式存储良好的扩展性,因此适用于非常大的数据集。常见的列式存储数据库有:HBase、Cassandra、HadoopDB 等。 + +#### 文档存储 + +准确来说,NoSQL 数据库文档存储实际上也是基于键值的数据库,只不过对功能做了增强。数据仍然以键值的形式存储,但是文档存储中的值是结构化的文档,而不仅仅是一个字符串或单个值。也就是说,由于信息结构的增加,文档存储能够执行更优化的查询,并且使数据检索更加容易。因此,文档存储特别适合存储、索引并管理面向文档的数据或者类似的半结构化数据。 + +从技术上讲,作为一个半结构化的信息单元,文档存储中的文档可以是任何形式可用的文档,包括 XML、JOSN、YAML 等,这取决于数据库供应商的设计。 比如,JSON 就是一种常见的选择。虽然 JSON 不是结构化数据的最佳选择,但是 JSON 型的数据在前端和后端应用中都可以使用。常见的文档存储数据库有:MongoDB、CouchDB、Terrastore 等。 + +#### 图存储 + +最后一类 NoSQL 数据库是图数据库。本书重点讨论的 Nebula Graph 也是一种图数据库。虽然同为 NoSQL 型数据库,但是图数据库与上述 NoSQL 数据库有本质上的差异。图数据库以点、边、属性的形式存储数据。其优点在于灵活性高,支持复杂的图形算法,可用于构建复杂的关系图谱。我们将在随后的章节中详细讨论图数据库。不过在本章中,你只要知道图数据库是一种 NoSQL 类型的数据库就可以了。常见的图数据库有:Nebula Graph、Neo4j、OrientDB 等。 + +## 图技术方面 + +来看一张 2020 年的图技术全景[^lan] + +[^lan]: https://graphaware.com/graphaware/2020/02/17/graph-technology-landscape-2020.html + +![Image](https://raw.githubusercontent.com/GraphCoding/graph-technology-landscape/master/GraphTechnologyLandscape.jpg) + +和图有关联的技术有很多,可以大致分为这么几类: + +- 基础设施:包括图数据库、图计算(处理)引擎、图深度学习、云服务等。 + +- 应用:包括可视化、知识图谱、反诈骗、网络安全、社交网络等。 + +- 开发工具:包括图查询语言、建模工具、开发框架和库。 + +- 电子书籍[^info]和会议等。 + +[^info]: 学习目的(非商业用途)可以联系[作者]((mailto:min.wu@vesoft.com)获取电子版。 + + + + +### 图语言 + +在上一节中,我们介绍了图语言的历史。在这一节中,我们对图语言的功能做一个分类: + +- 近邻查询:查询给定点或者边的邻边、邻点,或者是 K 跳的近邻。 + +- 图模式匹配(Pattern matching):找到一个/所有的子图,满足给定的图模式;这个问题非常接近于"子图同构映射(subgraph isomorphism)"——虽然两个看上去不同的图,但其实是一模一样的[^subiso]。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/samegraph.png) + +[^subiso]: https://en.wikipedia.org/wiki/Graph_isomorphism + +- 可达性(连通性)问题:最常见的可达性问题就是最短路径问题。泛化一些,这类问题通常用正则路径(Regular Path Query)的方式来描述——一系列联通的点组构成了一条路径,而该路径需要满足某种正则表达。 + +- 分析型问题:通常与一些汇聚型算子相关(平均值、count、最大值、点的出入度),或者度量所有两两点之间的距离、某节点与其他节点之间的互动程度(介数中心性)等。 + +### 图数据库(Graph Database)与图处理(Graph processing)系统 + +一个图系统通常会涉及到复杂的数据流水线[^biggraph],从数据源(左边)到处理输出(右边),会经过多个数据加工处理环节和系统;大的模块可以分为 ETL模块,图数据库系统(Graph OLTP),图处理系统(Graph OLAP),基于图引擎的应用系统(BI、知识图谱等)。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/graphpipe.png) + +[^biggraph]: The Future is Big Graphs! A Community View on Graph Processing Systems. https://arxiv.org/abs/2012.06171 + +虽然这两类系统都是与图数据和图技术相关的系统,也处理类似的目标,但是他们有着不同的起源和特长(及弱点): + +- (在线)图数据库目标是图的持久化存储管理、高效的子图操作。硬盘(及网络)是目标运行设备,物理/逻辑数据映射,数据完整性和(故障)一致性是主要目标。每一个请求通常只会涉及到全图的一小部分,通常可以在一台服务器上完成;单个请求时延通常在毫秒到秒级别,请求并发量通常在几千到几十万。早期的 Neo4j 是图数据库领域的起源之一。 + +- (离线)图处理系统目标是全图的大批量、并行、迭代、处理与分析,内存(及网络)是目标运行设备。每一个请求会涉及到所有的图节点,需要所有的服务器参与完成;单个请求的时延通常在分钟到小时(天),请求并发量通常为个位数。Google 的 Pregel[^Pregel] 是图处理系统的典型起源代表,它的点中心编程抽象与BSP的运行模式构成的编程范式,相比之前 Hadoop Map-Reduce 是更为图友好的 API 抽象。 + +[^Pregel]: G. Malewicz, M. H. Austern, A. J. Bik, J. C. Dehnert, I. Horn, N. Leiser, and G. Czajkowski. Pregel: a system for large-scale graph processing. In Proceedings of the International Conference on Management of data (SIGMOD), pages 135–146, New York, NY, USA, 2010. ACM + +![](https://docs-cdn.nebula-graph.com.cn/books/images/databaseandprocess.png) +[^iga] + +[^iga]: https://neo4j.com/graphacademy/training-iga-40/02-iga-40-overview-of-graph-algorithms/ + +### 图的分片方式 + +对于一个大规模的图数据来说,是很难存放在单个服务器的内存中的,即使仅仅存放图结构本身也不够。而且通过增加单服务器的能力,其成本价格通常成指数级别上升。 +此外,随着数据量的增加,例如到达千亿级别的时候,已经超过了市面上所有商用服务器的容量能力。 + +于此对应的,另外一个经常使用的方案,是对数据进行分片,并将每个分片放置在不同的服务器上(并进行冗余备份),以此来增加可靠性和性能。对于一些 NoSQL 型的系统,例如 key-value 或者文档型的系统来说,这个分片方式是比较直观和自然的;通常可以根据 key 或者 docID,来将每个记录或者数据单元(key-value, doc)放在不同的服务器上。 + +但是图这种数据结构的分片通常不那么直观,这是因为通常图是“全联通”的,每个点通常只要6跳就可以联通到其他任何节点; +而理论上早已证明图的划分问题是 NP 的。 +与此同时,当把整个图数据分散到多个服务器时,跨服务器的网络访问时延10倍于同一个服务器内部的硬件(内存)访问时间;因此对于一些深度优先遍历的场景,会发生大量的跨网络访问,导致整体时延极高。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/lessrpc.png)[^gpml] + +[^gpml]: https://livebook.manning.com/book/graph-powered-machine-learning/welcome/v-8/ + +另一方面,通常图有着明显的幂律分布;少量节点的邻边稠密程度远大于平均的节点,虽然处理这些节点通常可以在同一台服务器内,减少了跨网络访问,但这也意味着这些服务器压力会远大于平均。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/Power_Law_Distribution.png) + +![](https://docs-cdn.nebula-graph.com.cn/books/images/singleserver.png) + +因此,常见的图分片(Sharding)方式有几类: + +- 偏应用层面的分片:应用层感知并控制每个点和边应该落在哪个分片上,一般来说可以根据点和边的类型(比如业务意义来人为)判断。将一组相同类型的点放在一个分片,另一组相同类型的点放在另一个分片。当然,为了高可靠,分片本身还可以做多副本。在应用使用时,从各个分片取回所要的点和边,然后在偏应用侧(或者某个代理服务器端),将取回的数据拼装成最终的结果。其典型代表是 Neo4j 4.x 的 Fabric。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/neo4j4x.png) + +- 使用分布式的缓存层:在硬盘之上增加内存缓存层,并对重要的部分分片和数据(例如图结构)进行缓存,并预热这部分缓存。 + +- 增加(只读)副本或视图 (View):为部分图分片增加只读的副本或者建立一个视图,将较重的读请求负载通过这些分片服务器承担。 + +- 进行细颗粒度的图划分:例如将点和边组成多个小分片(Partition),而不是一台服务器一个大分片(Sharding),再将关联性较强的 Partition 尽量放置在同一个服务器上[^arr]。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/smartgraph.png) + +[^arr]: https://www.arangodb.com/learn/graphs/using-smartgraphs-arangodb/ + +具体工程实践时,也会混合使用上述几种方式。通常,离线的图处理系统会通过一个ETL过程,将图进行一定程度的预处理以提高局部性;而在线图数据库系统通常会选择周期性的数据再平衡过程来提高数据局部性。 + +### 一些技术上的挑战 + +在文献[^Ubiquity]中,对于无处不在的大图和挑战做了详尽的调研,下面是其列出的十大图技术挑战: + +[^Ubiquity]: https://arxiv.org/abs/1709.03188 + + +- 可扩展性(软件可以处理更大的图规模): 包括大图的加载、更新、图计算和图遍历,触发器,超级节点; +- 可视化:可定制布局,大图的渲染,多层次展示,动态(更新)的展示 +- 查询语言和编程 API:包括语言表达能力、标准兼容性、与现有系统的兼容性;子查询的设计和跨多图之间的关联查询 +- 更快的图(及机器学习)算法 +- 易用性(配置和使用) +- 性能指标与测试 +- 更通用的图技术软件(例如,处理离线、在线、流式的计算) +- 图清洗(ETL) +- Debug 调试与测试 + +### 一些开源的单机图工具 + +对于图数据库通常会有一个误解,只要涉及到图结构的数据存取就需要存放在图数据库中。这通常是一种误解。 + +当数据量并不大时,通常单机内存可以放下,例如数据量几千万的点边关系,使用一些单机的开源工具也可以取得很好的效果。 + +- JGraphT[^JGraphT]: 一个知名的开源 Java 图论库(library),其实现了相当多的高效图算法。 + +[^JGraphT]: https://jgrapht.org/ + +- igraph[^igraph]: 一个轻量且功能强大的 Library, 支持R、python、C + +[^igraph]: https://igraph.org/ + +- NetworkX[^NetworkX]: 数据科学家做图论分析第一选择, python。 + +[^NetworkX]: https://networkx.org/ + +- Cytoscape[^Cytoscape]: 功能强大的可视化开源图分析工具。 + +[^Cytoscape]: https://cytoscape.org/ + +- Gephi[^Gephi]: 功能强大的可视化开源图分析工具。 + +[^Gephi]: https://gephi.org/ + +- arrows.app[^Arrow]: 非常简单的脑图工具,用于可视化生成 Cypher 语句. + +[^Arrow]: https://arrows.app/ + +### 一些行业数据集和 Benchmark + +#### LDBC + +关联数据基准委员会(LDBC[^LDBC],Linked Data Benchmark Council)是由Oracle、Intel等软硬件巨头和主流图数据库厂商Neo4j和TigerGraph等组成的非赢利机构,是图的基准指南制定者与测试结果发布机构,在行业内有着很高的影响力。 + +[^LDBC]:https://github.com/ldbc/ldbc_snb_docs + +社交网络基准测试(SNB,Social Network Benchmark)是由关联数据基准委员会(LDBC)开发的面向图数据库的基准测试(Benchmark)之一,分为交互式查询(Interactive)和商业智能(BI)两个场景。其作用类似于 TPC-C, TPC-H 等测试在 SQL 型数据库中的功能,可以帮助用户比较多种图数据库产品的功能、性能、容量。 + +SNB 数据集模拟一个社交网络的人、发帖之间的关系,考虑了社交网络的分布属性、人的活跃度等等社交信息。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/ldbc.png) + +其标准数据量从 0.1 GB (scale factor 0.1) 到 1000 GB (sf1000),也可以生成 10 TB,100 TB等更大的数据集;其点、边数量如下表。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/ldbcsf.png) + + +## 一些趋势 + +### 虽然图的各种技术起源和目标并不相同,但在相互借鉴和融合 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/convergenceofcapability.png) + +### 上云的趋势在加速,对于弹性能力提出更高要求 + +根据 Gartner 的预计,云服务一直保持较快的增速和渗透率[^cl]。大量的商业软件,正在从 10 年前完全私有本地逐步转向基于云服务的商业模式。 +云服务的一大优点是其提供了近乎无限的弹性能力;这也要求各种基于云基础设施的软件必须有更好的快速弹性扩缩容能力。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/cloudtrends.png) + +[^cl]: https://cloudcomputing-news.net/news/2019/apr/15/public-cloud-soaring-to-331b-by-2022-according-to-gartner/ + +### 硬件趋势,SSD 将成为主流的持久化设备 + +硬件决定了软件的架构——从发现摩尔定律的 50 年代到进入多核的 00 年代,硬件发展趋势和速度一直深刻的决定了软件的架构。数据库类系统大多围绕“硬盘+内存”设计,高性能计算型系统大多围绕“内存 + CPU”设计,分布式系统面对千兆、万兆和 RDMA 网卡的设计也完全不同。 + +图基于拓扑的遍历有着极其明显的随机访问特点,因此大多数早期图数据库系统都采用了“大内存 + HDD” 的架构————通过设计**常驻**在内存中的一些数据结构(例如B+树、Hash表等),在内存中实现随机访问目的,以优化图的拓扑遍历,再将这些随机访问转换成 HDD 所适合的顺序读写。整套软件的架构(包括存储和计算层)都必须基于和围绕这样的 IO 流程来展开。随着 SSD 价格的快速下降[^ssdhdd],SSD 正在替代 HDD 成为持久化设备的主流。SSD 随机访问友好、IO 队列深、按快存取的特点与 HDD 高度顺序、随机时延极高、磁道易损坏的访问特点有着明显的不同。全部的软件架构也需要重新设计,这成为沉重的历史技术负担。 + +![](https://docs-cdn.nebula-graph.com.cn/books/images/ssdhdd.png) + +[^ssdhdd]: https://blocksandfiles.com/2021/01/25/wikibon-ssds-vs-hard-drives-wrights-law/ diff --git a/docs-2.0/1.introduction/3.nebula-graph-architecture/3.0-edge-key.png b/docs-2.0/1.introduction/3.nebula-graph-architecture/3.0-edge-key.png new file mode 100644 index 0000000000000000000000000000000000000000..86d8d118537ad5e797f4bba64a62676319161490 GIT binary patch literal 8574 zcmeHti94HH*SD6_R;yKYs%og#Jk=N!MYU=up=zq3v{WM^RWybe(oty%HH#rtq=u5C zsG){dQ&SNn5kljXl1hq0M4A}#MbCNO@A{tWeZD{7z25t}a%b;-@9e$TZ|!@n^;N?TWZ!b6%i!NM?aw5dv8PEd>PX z(hh9i_>Er|zGLedAs}$*A~ z57htL_|M2hTa+>>`+ukV8{z*B%rpRSnv-nt^WHlKjxXeBc3xmwp-hGqP>&#AO2_w`Q4`7X9B5M?DVZhi&!H&1_BTJAC?)Uma-6#Ms zSP|%=03`4j&Y0v!WQ7Blmr;;U$`wFLd)Zlt)6Y*98upItEVY6hd8CGWM(Smal z10#DDe0MRIMr8)AXQ-*4YcOD3$j298Zbc+YdG&l++x<8GE>rZB)M>L;GJphJGhL4V zsz4L(`9mG;?;k!*<-`&h1;@dk+ZTITHDHrB?(1U>HbFTbgV>Ew6Rsw)Gkhrs#oxA= zk!xf9)baR7w~SLF{U$M`_|fjb$G@N> zSQ&^BZw{nIL}ilE~OB+upzRF+N(BMG-GgJISu14Gp(r)T+WNdUWrxjI~lN4NWSaHJ594 zHW3*?HbEPy8)4XnhXDhpuOAwc_>MbWhFqUAFd+cuI1`uWRiKBmN-W^lA7J~Whl`(3 zR7iJd23xtHDro;o!+pj}BEG)-n%Z=Z@k@|CP;9t~JYSylrqVRxVK|i9XWTy)o;JFl zfUBn&)5E%B{XNqBq)d$^lsa(p;%LsyB>ME)NV##>_)^WTf%>lWI*L}08pG{HLPr-9Q!3Y!&T?vdt41s*hk#!F+4IT7u;|CC|a@G z*!l|NLwBo(GRy^`wB?Gev}=Jn9i=sIJCrXk8vyfuzTfR>goBN=0roI_D%NI(W-?=0 z-3iw})JRunz3R}6ZaA3tu<>-3C2Pv8Acy3KpFR7GwXa`y>X5ABWJ+g{~GOsLSq+ztN5lLf7A5p?7LVYwa;=D{~x5;~V4`F<8j+ zy4d6Mbv{1xzxD4-BAB{ebKr*Uu}%k>w)E zX^f1!(Sxulqhxh#)c51tK=Fc)IHgW;v=oHnD6!8sM z;bF#E&=;MztiMprx^JprIB+K~YO>$;B~^-2ySy!LG-t=z$1Fl8jmsSv{PJfTvn-|R;bAKlwfy>1jx9-l*T z^efFoZ7rvh#9f|?^OIl{Y8zNB{#Ti_(Ub5v3 zZnw{=x6lVQQbi2eS7yc@pT{E7#s_Ye@NLz_|0K7(hXvh5MzboI zWxjHhal!cbhSM;yHg{0G8P=!+j=#{7@-VA>I`5bbH>FiRC_uVyp*OK|-hlqS(U^8} z5sM!#9il0~tqC}p^XzX*?++gi;K~=gdn+ne>4p)0*n2DcVDw;#P0yjjlj;>T>#cn_ zBMX9g&_#q&Bg(_w}reqd$E4koWhZ@}-0(p9v4$PW`b*9LyY zPT-d&b*r(l#e=@UW?231iF=AMb27`9Ru3JtGfXxKY>sRy?gKa{0t4RN_*`fB!95I_ zCr+apw6B+;7n)kfi}`v{^N(BQOKhyS2lULrEO-3!-h%!Vp7TI>+wCJILq>mI#hz|a z**YG~`|`5h!NuT0%zDM`4wuB0!RW;WO53jX=CXtDuT~a#&0A4EMvx3?aEgpIJ|VSu zaT*ZzdI&KSZtuIhpVXEaaCzhFbFV;@JoU07@8-Z5lMlvP|GAk@Z6+o*L4MtU+0LO% zijj;UrE9CXV{sY62TnJq*T}egs@x%7zXln&Dmn*>X+ut|%Ph_(wCQGE73-YRhKjU# z4x8J{sx;`6o8lvv;S%7#T`3*sAKv8u@`++L{I<1nWWS=Y?t-_igz1_CCi!B`-mOvP zarF$<%b2Kxiwn;aUQQ2?Aff;jb{NE+2!oV5S9O9{-3N+;v>ZQaLin zh?pLAG4F?6MVtMD48=E`AQd>I>qMnZzOvy7#kS%MA;uo1PNqqpc3?ESN_o7hRqdN^ zJA@v8vVi1c0VmT%Y5+jk{a#5%cFT@u3Bslxv9GOJ8EB8y1#+gulb~kZaW8$jtxaOK z`BPEZmF*-zZ-nV(&oA2zU+!R6O@rEVg7_`k1hQ*Ey%uGk*Ug>gUu_? zjo*DMJ)Tv=k{xj*0Q!}_!Ha3dZ9=a#d_0&Z(F1D^-4kA56a^R(dfH4cvf|;m``pzc z7aQ6>GO_K0?z|;7l)^pFJrhVTY<5d_hM?e!K_ux=Xh$EbB*(4*Qb?BuIM00E()gA+ z!F>LoGg;k%>~d_FLwV(6u8Dgjd@?wW;RQ7IAavcQiZ^5x3Y$ zrEY)_ETdN1GHH7ABQNbMdwVtF3lnsSaQ9V4`gvtgfo4hWH}thMJzy1<2TPUD!X6}M+O*A~3xCL$GM~97LfJz2QA4m^t9RtKKr)?7p@LOMwO>g3j zIyie@JE=wEVL&B>&z!13IzTgc=+NuK%jO=Xi2xwh>2F>{YQ!v5^VXL`BW`}K za`G}C!l+?emeGjqt+cGv2@%djv9uil@WLn$ZC4)!QZSd|ul3h}MHscGmR}j3C2Ur9 z_6)<+EC5Ho!5`P=pK%Q^YUpAC<*$1Y++);)$06C^){AC@HPv1CG~IrcJJ1R5ltK*n zT&PZUkL?c0!?aVNDBpMgm;GG}K>3UONk;J6Z|AGdKSewfUtMrD*uN=VCb_GB4m5N_ z)61oMWq8bJqbwO79D6cQ)q+boMJqjfOj&uZIrL9+($z8S_wx1u5rT@f0zpOqv zNf}HK*^5Tvet(qr`}P?jjB*d1k?vF!E+QxdW6A||bBMxO#{Q_wwLK@pLd}1B>iN|? zPdvqqB0!ull@NOvoS>t_aw+r4j1^a*h^a?^hSh-2Pi!(5?B4&;kXUu3 zK10te^WnWggyE*z^oC-R9yw2$;=z*?B&WSNSOV22ZV<7vy6jLKiA3)4(b!K zoRVq{fMUwp>>u$4+Vp&-7a}V@U=%!Td4ZI#ynTdN#S@CirE>nXxLeIznY>h^2ejKR zVZTc8%kU5Hs_N8v+YeZwRmUQZ@RZaLiKef)nNu1-al}RD>&`f~h*wdXI|`GV!324k zZF}Tn$Qe9^ZOYu!&YV~b7_P<%VxhcYso8FW-~cObtqt{153?RJ(~E?iS=l7%gv;Sth1HLh}f;L-k2)3kyv%z#F za+`S1Zn=!LTXhaG--{3uHF~Ned|LD}!~An%hj7=qw@|?A6%fIQ7wU`t{Wkw>@T;+Jln}7B_~%X;^10u=>#{Z)f&?LPL0A?dt=# zk27;|S6iEwj$*)uwp4#xypk1l{rHKbpMl*xf)d@33^oL}_ZI3(*PF*pw zokqec$~_{YDCY3^rNSx=b0=M|Kpu zibJSJ6%sjp23dC379h2Or>@@!s_Zj_k)31-XqIft=Fm&Y)i{_YDKh+rJ6~p8We1~A zKC|w3u?<{_Ii%X8I10&WtKFLJD7BY{N6bm_`_w!627xGuvcdH2(zqGdfP)6g2FvB! zC$gYDQIu6RyG`)Eqr#d zoeZ#)l`eg({*6Otx#4x@D?6_&A5HC^YV^8+N-|inOff*pftez;0TI1<$UI0g6uX@4 z*Bza({K5J$SA*p%HdT=3o`)HU8;G9u6p!t`R*cQ5ewhXzPSXbOz|sDeXue=s3nfXv zOP9or6Av2erhaEQBUPTL44I8;8~ZV^#MlwXZd}c!qG}+a{4J@Y1%LnzPlITsL4cm+ zzf-a5yOpZo3sPgb=JIA&ASh zB>j{a%8+~^6Ka9v17PwQpk$pFYUpi45s6vHsj!IVcE@LqCY_o^ZC3u0LLQBo=kQ zFY@IzxD~QbuqP>M$%Q6p900HeUl5%aWvYEM2Zs(`6eC7bU+M$J@y|iM%P?PZm=}xE z%~No2!D=S99bK_&ffoYLuwR6F+J6@fkG@-Z&1@90Ah>jFw5L(D)Y%kE>iGm9g{KYK z)HD92-Uld$Sh~^|>TVQn?-cqb@*YG!!#mB#sq6T)&hz|uS8QHoZ77Y)cka#-Z_*<+ zeUHtIbm^A9wRjc|{0`GS(a4l2r^;f$03qTXAD39;b^F8wJUp}}}QADPf=V5HVDO8ZBHTdSN&qByq z$RK|m_sCKHB$$|LRf8^bT&*qmu`lCJ_%+vQ;hF>fPIuJ$u2t7>AGY%Mo<21=^L}@h zq;qYRa<>m!a<0|a!EUPXK%>RgGvhx-4pDR%8_`BV55B}s#J{Gs0{l23+ zM;^@p?=k6M3fhXc0&Shzm$I3}PkhnD(YSkO$lM5-B*Y@m#M&k2Dj~NL{qt>q%UPEM zJnZu4_dznUBu~V?m*xn=FyowvHG5O-VTd%3KSmOt`LADj7jae*lVa&FL6^jD?Owq$ z6=r-JG*)T@0s)Z`g`8aSSwE=$qD*ROsmVtGYt`9pvA|j6@Q%@H?}*xV-=T%rZotLM z;^&L*o-P$~99!nkgQW^^spKUxzz67a$_C%`Y`HVWJ(j`Qjy&K*dgv28e~#qA(Y;+CSwCj1WSENkeD1f zgIcMG`+a2Hq}$z=|7OD7_&#|U={TfL&2|X?ldbqrvv~2HJWThsv`E%QebT(jf$Is% z6AcHz2D>EFM@((l{1hEZ2~5r2zmRJ<;vTq5IA;B<{>mlU_A*ELgD}er2FYY|#|eto zbwcKwDbuYCcrZd=f&wI--Z97*u3eVYUz8VI+#_oCG0$nTIm*_L6!!6qFtnhSw4d<1 zWoV)N>gadiLsi}6E205_I>t2@+O?U9V!Q#a8Tru1WA?z5LR~FWA&?P$BcxoU=Qc^5 zU=_kRyPR6z(2}chI4tJ$EaEY^YBoKfF}3kWx$*n)OBTxWIMtPt32ww=6lTmIhj>9m zydE`sD)5ZohRPhh`RN&tjX4P=$7-O9(1J9w&T*|`u4=W=d1$%cMvUh1y2Xv3E*j-W zNQzVwUAa>kcM7gAlRSlg=_2E+DyR4qbz!i5`O8@!g<=-Ic->nvb3mc~QJEr`%)tH_F0H z|ImTs2RJx54jCF;w&LK}jpg9jWx4Mc;L6B}5ogx~H(xkIAo?ndqZOW@|i;0>|P?Uf}3ZBUrUoC+wcgT3{vxl?_q&Z9$PX>)am zJ|QLoG>wD9nuGB(@NxU<1@JE5^Eck3<~x^d_u#pAKCO5C7r1?kNcJ6;I26!N5>;>5 z`jhlF=$V3F{la+5E3r^1N&pak?i%^mIp3~mW8AKeN%_< z0Wh~C7FJ^T3gl7B>P0YhFGHg7nc7iGR)XdQ!@sY2i{T$FCyrhK-_l#Wz zk@;KW(4QE?f`dOL_3mYSxwcb~q2fPJ;g#<5o0IfX%2{-E>*}16aWtLY%r2S1h9;bD z-Wq9PiEVh+BgvD(G#o7ZRh66n9*3A~gay;qt}?AJ+hNqn0j&u9?g`}6SvNwHquSNm`EI2M zBcprFH{?xmDFsNg8`RMDwkK2WfZ1jGV&kWQ;IMFT6~u+Kz>6$#TYKtQ5Rf!e?k$hC zYfkrXcwV+#$1>@ShB@{xMkV}?NOXQH6ix4ZBl^VH-RNYw0YOlfUp#mBGxs546p2+g zIpeiJUow+#D{!03W>gkV+OO1=sjp_UH2A{!o&6Sq@_OCK6|OF&XD|UqA7fxV+Ai67 zk_R3*NAD|vMBYd%vmw*^T|KimbnmeANeYxQsBLJ4R_xdrXVt)_S~H+wnJs8Kjxim< z=-0w7m<|(>C8>*t3Qlq?akBkw%-uZZ`uw%LF8p`2~Do9nm zSx`;)Wx<#oBlPj@FX&n`{WfWsO&deYTQ2|uwKP4zxtNA@t`|R)AO^|b{b8VrkIG;h zm%SfH>k`rsprD3HySYhF6pNXpMgG)yQ_Pck&SOi}-#de%7VJ2VEO7H; zWGXvX!1KeV!?#`qJIr{XJWaAygJbHFl{S`3z)O}GlVD{b6v&OW$xjI%& zB`*fKJH#LFwvU31$WT;I`^WUf!Y8Lw zH6p4bq=|Ednw`Vpi{pxpStME!Mh9u-E7bo2ImlG57k#u-J$#k6k<-kaIn#~aoL*?+ z-4H$zcH38w;^rw;HQYzi;1R(Cpq9}67;ht5P5 z7H#0}R+UE~Jf+Mha|uR%YDYRgmGJg>ehl(7VxawtB2d)6H^0*A4voan&6}A0rMqh$ z{UaYJ*vpuecZe<+lT8Lc28AkdmHTO~t=Ukg>59#t@HW0wXEIO66DA$BvV=~qIQRQ= zca7}UcvzdDx!7rTvD;4qn-W_rvPQ(Q_+`!uyS#Gxx8QOFx#x%6H%)bS_J9MMQ?bSf7!f zx5k9J1cs|rNlExoAD0h5OfN`Fo_glTG-yx<%xjnc+d@kkSh>sHNmQWJhy2oQaJO>Q zKV^SXCmkxo_q;Yvkc%P^n=|CLf7#ou;V?zc-VAxjzI4U2Lh@Ja>D4=X-oCZ(yz3c~ zc~zcjc?JtvXtAG)GbKQ1())Ymp5d+#?b^6d@2`X``{8FC+2NGtq@;fg6_Ao;m*61@ z0|w9Kly&ZM>&jdL#SV?x#$=iZRK?vZNg4sxNJjaDv~PAi?+34gDBoeJ>X1orvUO~J z)LZfCNv}Bv*P_6%s5QpwsGbb<*c$m0()LUvt_Z>OSvVI^l-7yM9;qzuOwgzJ%U1c} z)^vVM5UY92^>=%2By9?FiyCL3xC)YX=h@Ytd^#&ARtAp8xQECSybf|=Q9hlWx%is- z3F_vwqTfVX|G{j~YQb7h-Mt#iwqX30a$AIpMk8)Rk>BvZ1a&U4GpD9Y6RK__Dqq_+ zU@|QVES~{1?Z0NVCx^X!9k*X~=4kV1si@G3?n=_cc*dZc&8>9yA>whyFu4|-JOp<* zg+=!;yiZ~iP4++9W3(HZ*0U%b1NDct`P~26h`yq}QjsOzhGj6?Ca$|sG?*nzsnV1W z8YC)$57IvkC03uC=lA1|l)4HRLN*NO)wJ|0He|yfL1uHg!IJ@sJ*r=Zse{m?ETg_m zon@5Vng|-C+!MXTTA$m%4fbk2)Vxq2#oow;uunxx{<$sh@nW5#lC?N?%M;(Tz2(u_ z43>k+bg8(_P)=6Slx@HcamECwjt`|T`;sToCk~-(M#|mlnoOL71~#24+W!uxp)b!v}chpRK->ePrBcXC^CP zb#$b6y)%JHC1Y{L33|;citwuUhdT=A@67JfP+{{&aFP78JklMHV)o~4TaWc^$34@% zR&tDD;=5dPK>ods?#<%J%Es2dY~w%?8j$Vg&s4PYQgCo}wU3$G!QLIUz_UvGZMG4O zS{_uy`9~$%DZS_(c|1h?y`Wl--5-nQ%aZ}9N3eZy5*<|A0V75wTK7)k^$lC*^<8Lc z5(!9cOu)QZBv5?9dc_lF2t_)BZ(@M&v=OvnH5CEQqBfuV5Uk4(9r7y_fz0o?N5xU| z#-Mq-)>)XEWNe!f_{EeUgwreB%bAX%&c^NZijOFr9J-#ooy$zMsOF*IXb3s>tt`*T z>IfiB~erATH`r-oFJUUqV%+pPbGJIdjuVEJJMC8gnMHks^V~zvpt=5 zavXnyvh~?)bRl4%&8aChEx8Vil?>>NXDn57nXHU^GBbB^EmkX3%r6&8 z$lhCdt`IXqNw5tMnmzX_FYMXfnH8oZ8C|Lvj~OsiJfEyiQ$MRPB2}dwk1I#Iqc7u; zx$M|A^5lRsANATrSw^*cc2VR6t_}Ah7_Vj1-U~l(1Aag(8p;n2F-gk_o(;*IP6d*R zlV6hx4M~V-yT@~cM{R2DWT8Naw&rBV$XXyNs-78`GTYG+>p3sMo879iukFix%;hKL382*+si@$upj5i0MCl!`W8H(QB5DPn0XS>tYLNujR^DF0JLtO~yoBoM}rtk(d93wE7~N zRevwGQMtDhCnt{;_Z5QD5O461t|w=+Nzl2r=&iCXW4jpA*Xl{p&^E#82byTe zcN8Nl(c8KJjXJ`Ti&%e=T7Q!$E`%xbxd-Eb;w;ebFR)~=^4;DEWBEccY4(4RE7w1W zucRcuDv`a8waieSDB21d8B&}%9s8&sH9%6BOcttX@ez2H%@D00%N6M5S>|hYe6Peu z)yk9Cqvb+pQbm8C7t`6Xt?DG)uB>#A}^!dza}9dL+PnD+x%yK=c} zDSG8q>4@$iYD)r#nrYJtrVjTV#N0V(7>mhrTEMj*GbhxV#*l1<~zqF=RP#Gj#l)m8R`4|I)s~Z&R+LqXG4-7Ig6`mEYp7&*lQMd$hpby~&;@$nR>aOf zKi>KV_x_1M-hVw<`%h1yDOrqiAvMF6;T4?zVZX>vxImF2a>jhv`ltB^SOb7C4>J-T z9A01z+w5@YvgVDcmeX3SPviWfpU&UQ4Em=B#s60k_rECgzbN#-DD=N5G;nnBFADu1 zP-uGW#we$v$s8HMoTf`0w5x?k%_{GT?*Ch|FAkez{eOEm8Qd8#Li;3X(oj!xK}oxqg!6X>L8AQ`gS8tNB91 z8)nbNPz#{C8^;}?;yP`QY#-nwZP9#a zlxMQOxfp)xWbisOYHi8;d1n!__b_taeaK^ahm7Ar_`Xq(DcHVUvHc{VtPZ}lpz(lh zvEJJoU2q^dI?^H>!`PO}W~m8y;R6&W7HvIAUtn%U6e8L0meBr3gf6b6@rhI@O%TRu z+z{t_ADDtE59AP|TDf2k{MIol&Gw`Sx0d`u5^Wbl!#jhb7t%dSif%wYQ1_FJ^z0rbFc6 zBEcFJTI)Fx%&LO}SW*WI=T6@vw|yC-m2xiRewV@9hPbE_9&@rSk2ES7lZWB^qt-N} zVaG!t-67x!0hBi9^XxTr`3AyIoj z3=r8ppQIiE=F57r%n3RvTmnph_=Y&sT8B z22PRV_onW>%D_L~5G%R^2m?Oy85(d%ZjAl|$-kjLKj2aJ?-x zn_}-s_sa7S@w_A`qj}~Et6~KL;B=?xcfN`c>H~qq_2fN`d9{y=5}wu3(&ETNsSrZX z+SyUMHDC|`BM22JeOTMHh@1=gn}3|7OJSw>1Y2`GI9>19LBJgr<3h$fP2O8c?Y!nr z6&7NMw4u^6s|a(VO!qX~u9ej%EM2iiOieeAM)}EJxR*3fH;`-62+kaN zt7-M;N+`0_U9X>?r0-pjB0?5s2p>=JeKaISvK?$v))S{SS#A?p?lfvSPK56nm!HFG z8dFX5h43p+{n>!OIq7pB&lFOUpeG4SDvC!T5=D2U4EHl1Acds!{!@W+D>g~TR~}dQXyi0?^$&H{`ZdH2eVjOxe5>Xv z%l;R~%D9-9eO^=uXQ(j)jhw7b=@*1nmN51Ec}Op+QS?Bu`m#1V@Hq60Xp2Tue2M#f zWNZ?J9?`30Y^T~(y@N+1#tU%ot9RNO(S@rVb0&Vl`9SC@zr{dP2|5$v)}3-8eXl{6 zVo*_(J)Zlryu7#7Z%AU5>b3YiknPoi^(NxI?#!$JZesM zY#;#y{LDPj>-r%O{W7u72f{s$+Pjdx`>dO_n z5gESH9-g}tduS=Ky)O3i)z6=V==rpv3s(Dsyqb%%<;2lcgPaxTPvy!R>P?-1fhWS(ukfq>@hL@2*V?rNd! zA>LL|mt#g$YgAgGCoa9EL1F!2asfbr zzK>{1e5AjUSekk~#sq(`O&@i!o zOzt`q9p~!IRTFD@@tEv;wxh1WTf5HPx+pZEzk9=}c)2^uMC__Woomax03saSsGP=^>H>6rkUf*-OdZq4NzlK@E zgQn&WoG~~6ka{~Z8{lay=egx_W&48b4lXsN3j^NHNdo#T#HMaecZ9DCp5BGTAWMBF zI7`!aPJbq<+-F1}O(z0Z!Dd0;0Fi(AZBf|c*I9faw)Qu?PLH?>As?X6SL9CFjXTL= z<=@sB*SRP+^(mngfUegZPk~zpbcES~eCaU-ug{4b`6{0i^7o|){-2?;mpVFgHChe6ylq1 z>R|wnxqsNdOJxsT1XHx5VXSZZgfHs9A5)cYnoG5x8Q|@24-RU5J=XEvM+;&9_d?90 z_@&LSiigj|e^LIOjHYk=_v*|`M=47?(ui;E_##ES59}Ux^s)2NbOa&8Z9! zO%GsAVc^Kccg@M2_RoKdN9Dv$^HgSaLIazMSPC6=l|QZS+G!}gGoMx@Xw0kMp>v$# zL9{bcj7^J)JmpMZq&sX|z1>DKy&i0@_l0>l?fpY(N7;PtmMX7#^PI?-a=!^IGpGIK zOEcuF;fl~XQf+ss3^*q?@*k?VD1%()f{o24eoCU`~8e4;q7kRL>{{hV*D z*Z4KDKJjnU|C}k=WwsYkNZ$^CEx9Np@(^pNl3ApPV2HtqtF{yElSlc6i>Ni?G4$rm zBimC(;O(h1E@6_{(Wf(YR%0(Wug$NG9;bIUvlRWpT7x%V9|KH9_z0M)S@J=Iv1ZeX z*1fe1@kB0%{Uz1fsu}gaXotSo!jumEWbymYRuctM?RR%`{9(PLO(0l^11ghqEcN>^ zFvjrtSaQk}d+UPs!qPiKyDfg&F_or2A58|eTyO6A1Hf3i@E*x{kP^WC+ z8S<9rIXrhn;7{~Bb--JEuM)52pk?-4O`_dsMce8XbQUWZ4yxWR+L_{Ar(nS5IYxrx z$uC>}2|p`;G~J$aQcN(}^0%zZTHP7G-S~h@N6oJrs&dM91N!oF{6M;S5u78rGg&gv zfA*9vt{sVar^uHl_kSMF!=Ig`Qi2tADk5PYaCiUbyMX`HN_;K>I34&a5lD}J-jSu> zHr~w`KKfaxuJB*u!H1IgC19_Zc)xB2iV+@V{{@}Wuu4%IS^G3Tazrzs^wi2Oj>%m+ zHu)Nq=*s_e7eaX`=e3!2GoVAcKIO=;b}rh+Mp@)ceS!1)R=>!#Pi+0Bbl)*$jR%O? zLAtLzd1xt)-W<8!`-mdy9J$m}GdCsY(fXl2{osmSEPg=rZKMY)(&8GB0wOacX|aB)EK4divI*#&=E`b=nhCTG2kyKCylkDYU+)lq6}I z4r{%Ed3_W4*TOCe5kPNZpjZ6yl)R;+nftprx_$z@aW;eq*<*9r?q*JnZMw9Ll#zwp zdV)2`X$Q?orZwrs#^gz~C};cRLSbC)cUs*Fyv@=59mk&R>`p?vPxk6Nf8^}vSIF8wX?-cEh($XM3M%5_xZ;kYddIIkOpHud^OLJa7NLZ6M6&Jf!rX&rQV#R0*PVt{zgKbVDmK0B<~)`Y zG_5GVv|=yr#cWqRFs!W+91oG z>c?@wY=2E|v!}@SWGuwoT<`WcgF_LN_8_-$criJ<7M z9ffpe&>CARerCPV%2&IOubCr*>udjjocz7rNnX1DeFG)93+MB$es?8|fnF$|xsyY+ z^N#*{zD(w`{QF4N=_W+<+T0HLfPo|*4#o-)`T?O%$y9}sYj#~6v7*1tk&$%s0HxRL z>wI2p+u>zJ{hQ2jwR!gMEw8i?3*)1EwSo}qxYLKtHJ9RAD#qBI;~NWGh3oAn&lnhg zNJWIMzOA?_9`n=^{`fthrdXHbO-8RrZmS}se0dfE#!pS7Ut^=H{J$~q?) zz!K*P<)w_Xy`$+`6+aW%G83ysWyA3Ueh>nL#E3ncfOI*uhvUiKqm;OW>+J4rX4kmd z*y3u-iwNnb+FSMK4{I}woBh`rF5w;H*_*>JV3Zh-JvWMkxy=c>4qw&SwYjx=$|2XY zO7NgI{Z<}Eqf1H31b zS6~gu4Zci4LA#4XKOp0PG!BksjvW?!xAN*TUvBIBw|-ftc3|>%cP>wV&Q|M8{w_rP z%j-psQlCT8Ji7Qq!WS8@0{7=RcuUXvp~06olTyCSn;p|U`;x_y|It)+hS-?G_CS~) zKz)Rnm&PHGQ&={1oN**(L5V%~9vZn%+c*v}@9ro{mYLxDyN5-nNOs{SbRodi@Ka>$ zpe#GUv|w{B3s81MHm9)^k3i+h>hF7RsXw!RNsocOfEOW53g-Y!WiVH}=X1z|x$U{( zxv97*5&uD><80jtQEsE{?)5s*wUQnk4lg|Dk1}cgDjDnzinw6htjoM zEVL_;*71rdC^{A;9sZ@9dXF5fPs&wJF0A9re9xmo3o)*duo=397vzPlCtWzK6p@~; zWI@afElyr5F!{c-M)?4zN|VK=?^!~pcA+ycA~nE^1truBj8@PJ4*&YezttMv{;D;! z^j=o2{ti-w5>1e^5%HG|dvO!!>Uqmdr#?DE|K~s?JRBb!ItU1t0IV~mTC@d6Kb|`S zm1v(AT5)M`kz%i3@P44%gr_DW^VxAESyCw=f^$>~Abw{P`C4Wv_J*7NdUfc2^-YM3Zf4h7JLCxI>*QES1%VTmWSo644Ek> z9n4?5;66eg0B$h{z95=-`2Br_Kjh8+7!GvqQWBCRx4LJ1CSNA z3w~$+R-QY*0ucs4P!KM+vlF?s7aaa*Fy-0H&G|CQ(8}$iKP&f*tcTey46p*f>&pq= z2)!4d$Bwar{#pHVk>YYyHE3SQFSmMQJ?6uR&%35%YjR$~C$Gk8&C~xw`ZVbAJ$)kQ z{ewQqd`Yo(rmWHZ12@pP!h?h;6<_|SH-t(+BRFdx?(i1Bdsav59w)o&n?{iDja5=s z4(l2Y=V*vVzwi1Y5&VG6RFbRyA4&ux8s$1ANLs4{8hxb)$GFE%s(IXVZk&%VG3xa?&7LWi2K1Udd2YHM1K)bebuh+qwpJz8}VU4Nv=E&`!&4E#Y zlBITdLsM-WeC)e04}rSkV)sv=FV`4~(JN@P0q`*y=!wFznJd9%=(4xf%s0&gBVZVU{rhyrZ)3Yz*1fqoYQ1CWwr zldaXiC-ytV`Hz4TP@I~ApL3Pa(uo?*esR-SgKYOiIsvz?q0yXYBqs03lva}7bJoZv z{8cY`2O%9c{GHhb^3p*%#h9TZ4_@rgow+H77knciGKTn15~QXiyg&)0vZTzRKc$f) zdQG{lIu{9M_v$J3|HzPr;GCZmyPeVNt^JE2Uau#oYAJ62OfRMl@Lz&*;(nSHqd31) zbD3{}i%}JC7ziM^x_7ncigd40@((}9>%2;Cz}rbuJgTFI{LIvS;}D_244&~UA<6*{ zP=K*+xyE6X|t?Tt+k|F-WUy_uZpAhpUEPxsQyaF@~e0TF>te?|IEt^qK2?+d={Ujr#I-?*GEd3&0JI zKV&~+AC8v?KBEwh;@zJa3df7vi2vVj9}qsgEd~?8;6a%@(?C}^40X*em+Jg>_rC!& Cmv@)| literal 0 HcmV?d00001 diff --git a/docs-2.0/1.introduction/3.nebula-graph-architecture/3.graph-service.md b/docs-2.0/1.introduction/3.nebula-graph-architecture/3.graph-service.md index 2243ebd1dad..868aaf5f726 100644 --- a/docs-2.0/1.introduction/3.nebula-graph-architecture/3.graph-service.md +++ b/docs-2.0/1.introduction/3.nebula-graph-architecture/3.graph-service.md @@ -84,10 +84,6 @@ Validator 模块对生成的 AST 进行语义校验,主要包括: 如上图所示,探索到节点 `Filter` 时,发现依赖的节点是 `GetNeighbor`,匹配预先定义的规则,就会将 `Filter` 融入到 `GetNeighbor` 中,然后移除节点 `Filter`,继续匹配下一个规则。在执行阶段,当算子 `GetNeighbor` 调用 Storage 服务的接口获取一个点的邻边时,Storage 服务内部会直接将不符合条件的边过滤掉,这样可以极大地减少传输的数据量,该优化称为过滤下推。 -!!! Note - - Nebula Graph {{ nebula.release }} 默认没有打开优化。 - ## Executor Executor 模块包含调度器(Scheduler)和执行器(Executor),通过调度器调度执行计划,让执行器根据执行计划生成对应的执行算子,从叶子节点开始执行,直到根节点结束。如下图所示。 @@ -120,6 +116,6 @@ Nebula Graph 的代码层次结构如下: 用户也可以通过视频全方位了解 Nebula Graph 的查询引擎。 -- [nMeetup·上海 |全面解析 2.0 Query Engine](https://www.bilibili.com/video/BV1xV411n7DD)(33 分 30 秒) +- [nMeetup·上海 |全面解析 Query Engine](https://www.bilibili.com/video/BV1xV411n7DD)(33 分 30 秒) diff --git a/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md b/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md index 8793fae60f5..e5d7c6c44ef 100644 --- a/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md +++ b/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md @@ -70,47 +70,38 @@ Nebula Graph 使用自行开发的 KVStore,而不是其他开源 KVStore,原 - 支持多个图空间,不同图空间相互隔离,每个图空间可以设置自己的分片数和副本数。 - + |`Type`|key 类型。长度为 1 字节。| + |`PartID`|数据分片编号。长度为 3 字节。此字段主要用于 Storage 负载均衡(balance)时方便根据前缀扫描整个分片的数据。| + |`VertexID`|点 ID。前一个`VertexID`在出边里表示起始点 ID,在入边里表示目的点 ID;后一个`VertexID`出边里表示目的点 ID,在入边里表示起始点 ID。| + |`Edge type`|边的类型。大于 0 表示出边,小于 0 表示入边。长度为 4 字节。| + |`Rank`|用来处理两点之间有多个同类型边的情况。用户可以根据自己的需求进行设置,例如存放交易时间、交易流水号等。长度为 8 字节,| + |`PlaceHolder`|预留字段。长度为 1 字节。| + |`SerializedValue`|序列化的 value,用于保存边的属性信息。| + ### 属性说明 Nebula Graph 使用强类型 Schema。 @@ -123,26 +114,25 @@ Nebula Graph 使用强类型 Schema。 ![data partitioning](https://www-cdn.nebula-graph.com.cn/nebula-blog/DataModel02.png) - diff --git a/docs-2.0/1.introduction/3.nebula-graph-architecture/edge-division.png b/docs-2.0/1.introduction/3.nebula-graph-architecture/edge-division.png new file mode 100644 index 0000000000000000000000000000000000000000..a0a9ae36c732d9a9def2abdfa4b91332a63a5081 GIT binary patch literal 67790 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�P7={qg4cLEy_- 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 +从 3.0.0 版本开始,在配置文件中添加的 Storage 节点无法直接读写,配置文件的作用仅仅是将 Storage 节点注册至 Meta 服务中。必须使用`ADD HOSTS`命令后,才能正常读写 Storage 节点。详情参见[管理 Storage 主机](../4.deployment-and-installation/manage-storage-host.md)。 ### 如何处理错误信息 `To get the property of the vertex in 'v.age', should use the format 'var.tag.prop'` @@ -192,6 +190,10 @@ Got 1 rows (time spent 1235/1934 us) - 第二个数字`1934`表示从客户端角度看所花费的时间,即从客户端发送请求、接收结果,然后在屏幕上显示结果所花费的时间。 +### 为什么在正常连接 Nebula Graph 后,`nebula-storaged`进程的端口号一直显示红色? + +`nebula-storaged`进程的端口号的红色闪烁状态是因为`nebula-storaged`在启动流程中会等待`nebula-metad`添加当前 Storage 服务,当前 Storage 服务收到 Ready 信号后才会正式启动服务。从 3.0.0 版本开始,Meta 服务无法直接读写在配置文件中添加的 Storage 服务,配置文件的作用仅仅是将 Storage 服务注册至 Meta 服务中。用户必须使用`ADD HOSTS`命令后,才能使 Meta 服务正常读写 Storage 服务。更多信息,参见[管理 Storage 主机](../4.deployment-and-installation/manage-storage-host.md)。 + ### 为什么 Nebula Graph 的返回结果每行之间没有横线分隔了? 这是 Nebula Console 2.6.0 版本的变动造成的,不是 Nebula Graph 内核的变更,不影响返回数据本身的内容。 @@ -306,14 +308,12 @@ nebula > MATCH (s)<-[e]-() WHERE id(s) == "given" RETURN count(e); #入度 ### 日志文件过大时如何回收日志? - ### 如何查看 Nebula Graph 版本 @@ -339,9 +339,11 @@ $ ./nebula-graphd --version 执行`rpm -qa |grep nebula`即可查看版本。 + 进行快速扩缩容,详情参见[集群操作-扩缩容](../nebula-dashboard-ent/4.cluster-operator/4.manage.md)。 +用户可以使用 Dashboard(企业版),在可视化页面对 graphd 和 storaged 进行快速扩缩容,详情参见[集群操作-扩缩容](../nebula-dashboard-ent/4.cluster-operator/4.manage.md)。 Nebula Graph {{ nebula.release }} 未提供运维命令以实现自动扩缩容,参考以下步骤: @@ -355,7 +357,7 @@ Nebula Graph {{ nebula.release }} 未提供运维命令以实现自动扩缩容 - graphd 的扩容: 在新机器上准备 graphd 二进制文件和配置文件,在配置文件中修改或增加已在运行的 metad 地址,启动 graphd 进程。 -- storaged 不支持扩缩容。 +- storaged 不支持扩缩容。 --> ## Nebula Importer diff --git a/docs-2.0/20.appendix/history.md b/docs-2.0/20.appendix/history.md new file mode 100644 index 00000000000..26cdfd689dc --- /dev/null +++ b/docs-2.0/20.appendix/history.md @@ -0,0 +1,42 @@ +# Nebula Graph 年表 + +1. 2018.9.5 由 @[dutor](https://github.com/dutor) 提交了第一行代码。 + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/dutor.png) + +2. 2019.5 发布了 v0.1.0 alpha 版本, 并开源。 + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/alpha-bj.png) + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/alpha-hz.jpg) + + 此后一年内陆续发布 v1.0.0-beta, v1.0.0-rc1, v1.0.0-rc2, v1.0.0-rc3, v1.0.0-rc4 + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/v010.png) + +3. 2019.7 在 HBaseCon 第一次公开亮相[^Hbasecon]@[dangleptr](https://github.com/dangleptr) + + ![image](https://www-cdn.nebula-graph.com.cn/nebula-blog/HBase01.png) + + [^Hbasecon]: Nebula Graph 1.x 版本支持 RocksDB 和 HBase 两种主要的后端,但在 Nebula Graph 2.x 版本取消了默认对 HBase 的支持。 + +4. 2020.3 在 v1.0 开发的收尾阶段,启动了 v2.0 项目的研发 + +5. 2020.6 发布了第一个正式大版本 v1.0.0 GA + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/v100GA.png) + +6. 2021.3 发布了第二个大版本 v2.0 GA + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/v200.png) + +7. 2021.8 发布 v2.5.0 + + ![image](https://docs-cdn.nebula-graph.com.cn/books/images/2.5.0.png) + +8. 2021.10 发布 v2.6.0 + + 更多信息,参见[Releases](https://github.com/vesoft-inc/nebula/releases)。 + +9. 2022.2 发布 v3.0.0 + + 更多信息,参见[Releases](https://github.com/vesoft-inc/nebula/releases)。 \ No newline at end of file diff --git a/docs-2.0/20.appendix/releasenote.md b/docs-2.0/20.appendix/releasenote.md index 4cacf092f23..93091d769af 100644 --- a/docs-2.0/20.appendix/releasenote.md +++ b/docs-2.0/20.appendix/releasenote.md @@ -1,6 +1,145 @@ # Nebula Graph {{ nebula.release }} release notes -TODO +## Feature + +- 新增[备份与恢复工具BR](../nebula-br/1.what-is-br.md)。 [#3469](https://github.com/vesoft-inc/nebula/pull/3469) [#1](https://github.com/vesoft-inc/nebula-agent/pull/1) [#22](https://github.com/vesoft-inc/nebula-br/pull/22) + +- 支持 [openCypher 多 MATCH 查询](../3.ngql-guide/7.general-query-statements/2.match.md)。 [#3519](https://github.com/vesoft-inc/nebula/pull/3519) [#3318](https://github.com/vesoft-inc/nebula/pull/3318) + +- 新增[存算合并版](../4.deployment-and-installation/standalone-deployment.md)。 [#3310](https://github.com/vesoft-inc/nebula/pull/3310) + +- 新增[存储引擎的 kv 分离](../5.configurations-and-logs/1.configurations/4.storage-config.md)。 [#3281](https://github.com/vesoft-inc/nebula/pull/3281) + +- 新增`LOOKUP`支持 topN 下推。 [#3499](https://github.com/vesoft-inc/nebula/pull/3499) + +- 新增[不带 Tag 的点](../3.ngql-guide/12.vertex-statements/1.insert-vertex.md)。 [#3316](https://github.com/vesoft-inc/nebula/pull/3316) [#3335](https://github.com/vesoft-inc/nebula/pull/3335) [#3328](https://github.com/vesoft-inc/nebula/pull/3328) [#3286](https://github.com/vesoft-inc/nebula/pull/3286) + +- 新增[参数化查询](../nebula-console.md)。 [#3379](https://github.com/vesoft-inc/nebula/pull/3379) + +- 新增[不指定 VID 的查询](../3.ngql-guide/7.general-query-statements/2.match.md),通过`LIMIT`子句限制输出结果。 [#3320](https://github.com/vesoft-inc/nebula/pull/3320) [#3329](https://github.com/vesoft-inc/nebula/pull/3329) [#3262](https://github.com/vesoft-inc/nebula/pull/3262) + +- 新增 [duration](../3.ngql-guide/3.data-types/4.date-and-time.md) 数据类型和函数。 [#3338](https://github.com/vesoft-inc/nebula/pull/3338) + +- 支持 Schema 使用大部分 1~4 字节的 [UTF-8 编码字符](../3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md)。 [#3380](https://github.com/vesoft-inc/nebula/pull/3380) [#3440](https://github.com/vesoft-inc/nebula/pull/3440) + +- 新增[查看指定用户权限](../7.data-security/1.authentication/2.management-user.md)。 [#3300](https://github.com/vesoft-inc/nebula/pull/3300) + + + +## Enhancement + +- 重构集群管理。 [#3343](https://github.com/vesoft-inc/nebula/pull/3343) + +- 当日志磁盘空间不足时,支持改变日志级别。 [#3576](https://github.com/vesoft-inc/nebula/pull/3576) + +- 支持反引号中的任何字符串作为 Tag 名称。 [#3424](https://github.com/vesoft-inc/nebula/pull/3424) + +- Storage 服务通过心跳将 partition 的磁盘路径信息发送到 Meta 服务。 [#3369](https://github.com/vesoft-inc/nebula/pull/3369) [#3416](https://github.com/vesoft-inc/nebula/pull/3416) + +- 添加对无效密码尝试的限制。 [#3573](https://github.com/vesoft-inc/nebula/pull/3573) [#3629](https://github.com/vesoft-inc/nebula/pull/3629) + +- TOSS 支持`DELETE`操作的一致性。 [#3374](https://github.com/vesoft-inc/nebula/pull/3374) + +- 支持对接 logrotate。 [#3541](https://github.com/vesoft-inc/nebula/pull/3541) + +- 支持更多的统计。 [#3446](https://github.com/vesoft-inc/nebula/pull/3446) [#3605](https://github.com/vesoft-inc/nebula/pull/3605) [#3590](https://github.com/vesoft-inc/nebula/pull/3590) + +- 增强日期解析器。 [#3179](https://github.com/vesoft-inc/nebula/pull/3179) + +- 删除 meta 服务中的读锁以减少读写锁的副作用。 [#3256](https://github.com/vesoft-inc/nebula/pull/3256) + +- 重构存储索引,解决节点间耦合严重的问题。 [#3196](https://github.com/vesoft-inc/nebula/pull/3196) + +- 支持指定`round()`函数的浮点精度。 [#3178](https://github.com/vesoft-inc/nebula/pull/3178)ß + +- ES 客户端支持 https。 [#3150](https://github.com/vesoft-inc/nebula/pull/3150) + +- 将版本信息移到心跳之外。 [#3378](https://github.com/vesoft-inc/nebula/pull/3378) + +- 支持空的列表、集合、映射。 [#3302](https://github.com/vesoft-inc/nebula/pull/3302) + +- 支持创建地理索引时指定 s2 区域覆盖参数。[#3396](https://github.com/vesoft-inc/nebula/pull/3396) + +- `SHOW HOSTS`中新增版本信息的显示。[#3702](https://github.com/vesoft-inc/nebula/pull/3702) + +## Bug fix + +- 修复 nGQL 中未指定值时使用默认值的情况下,存在内存没有释放的问题。 [#3666](https://github.com/vesoft-inc/nebula/pull/3666) + +- 修复无法使用`coalesce()`函数的问题。 [#3653](https://github.com/vesoft-inc/nebula/pull/3653) + +- 修复批量插入时,由于 Tag 已创建索引而导致查找结果错误的问题。[#3627](https://github.com/vesoft-inc/nebula/pull/3627) + +- 修复表达式超过深度时的崩溃问题。 [#3606](https://github.com/vesoft-inc/nebula/pull/3606) + +- 禁用 nGQL 的`YIELD`子句和`WHERE`子句中的聚合函数。 [#3597](https://github.com/vesoft-inc/nebula/pull/3597) + +- 修复在`UNWIND`、`WHERE`子句中使用聚合函数时的崩溃问题。 [#3397](https://github.com/vesoft-inc/nebula/pull/3397) [#3355](https://github.com/vesoft-inc/nebula/pull/3355) + +- 修复使用旧 Schema 版本值重建标签索引的问题。[#3332](https://github.com/vesoft-inc/nebula/pull/3332) + +- 修复使用`GO...REVERSELY`查询结果会包含过期边的问题。 [#3536](https://github.com/vesoft-inc/nebula/pull/3536) + +- 修复 CentOS6 中估计内存信息的错误。 [#3534](https://github.com/vesoft-inc/nebula/pull/3534) + +- 修复当`LOOKUP`语句包含一个过滤器,该过滤器由一个逻辑 AND 表达式和一个只有一个元素的 IN 表达式组成时的崩溃问题。 [#3525](https://github.com/vesoft-inc/nebula/pull/3525) + +- 修复 metad 在高负载下挂起的问题。 [#3482](https://github.com/vesoft-inc/nebula/pull/3482) + +- 修复`UNWIND`子图的崩溃问题。 [#3506](https://github.com/vesoft-inc/nebula/pull/3506) + +- 修复重建索引时`DROP SPACE`的崩溃问题。[#3406](https://github.com/vesoft-inc/nebula/pull/3406) + +- 修复 cgroup v2 下读取内存统计的问题。 [#3419](https://github.com/vesoft-inc/nebula/pull/3419) + +- 修复`DROP TAG INDEX`会删除同名边索引,删除边索引时也会删除同名 TAG 索引的问题。[#3413](https://github.com/vesoft-inc/nebula/pull/3413) + +- 修复克隆空间后无法显示边的问题。 [#3351](https://github.com/vesoft-inc/nebula/pull/3351) + +- 修复索引存在检查的问题。[#3315](https://github.com/vesoft-inc/nebula/pull/3315) + +- 修复执行`ALTER`语句后获取类型属性时可能导致存储获取空指针的问题。 [#3325](https://github.com/vesoft-inc/nebula/pull/3325) + +- 优化 raft 从而确保系统更稳定。 [#3172](https://github.com/vesoft-inc/nebula/pull/3172) [#3435](https://github.com/vesoft-inc/nebula/pull/3435) [#3358](https://github.com/vesoft-inc/nebula/pull/3358) [#3322](https://github.com/vesoft-inc/nebula/pull/3322) [#3031](https://github.com/vesoft-inc/nebula/pull/3031) + +- 内存比率大于 1.0 时取消内存检查。[#3289](https://github.com/vesoft-inc/nebula/pull/3289) + +- 修复使用 Ninja 编译时的错误。 [#3195](https://github.com/vesoft-inc/nebula/pull/3195) + +- 修复同时创建同名 Tag 和 Edge type 可能都成功的问题。[#3735](https://github.com/vesoft-inc/nebula/pull/3735) + +- 修复当不同的图空间中存在相同的 Tag 或 Edge type 的内部 ID 时,创建全文索引失败的问题。 [#3747](https://github.com/vesoft-inc/nebula/pull/3747) + +- 修复`YIELD`子句和 `GO` 语句中变量不一致的问题。[#3430](https://github.com/vesoft-inc/nebula/pull/3430) + +- 修复当 Schema 版本大于 256 时的崩溃问题。[#3893](https://github.com/vesoft-inc/nebula/pull/3893) + +## Incompatibility + +Nebula Graph {{ nebula.release }} 不支持 v2.x 的大部分生态工具,请升级[生态工具](6.eco-tool-version.md)。 + +- 在配置文件中添加的 Storage 主机无法直接读写,配置文件的作用仅仅是将 Storage 主机注册至 Meta 服务中。必须使用`ADD HOSTS`命令后,才能正常读写 Storage 主机。[#3343](https://github.com/vesoft-inc/nebula/pull/3343) + +- 禁用 ZONE 和 GROUP。[#3776](https://github.com/vesoft-inc/nebula/pull/3776) [#3825](https://github.com/vesoft-inc/nebula/pull/3825) [#3330](https://github.com/vesoft-inc/nebula/pull/3330) + +- 禁用`BALANCE DATA`。 [#3756](https://github.com/vesoft-inc/nebula/pull/3756) + +- 将默认会话超时时间从`0`修改为`28800`秒,范围从`1`到`604800`秒。 [#3357](https://github.com/vesoft-inc/nebula/pull/3357) [#3807](https://github.com/vesoft-inc/nebula/pull/3807) + +- 添加`SHOW LOCAL SESSIONS`和`SHOW LOCAL QUERIES`命令,并弃用`SHOW ALL QUERIES`。 [#3488](https://github.com/vesoft-inc/nebula/pull/3488) + +- 从点至少有一个 Tag 修改为可以没有 Tag。`DELETE VERTEX`修改为默认只删除点,不再删除该点关联的出边和入边,此时将默认存在悬挂边。 [#3316](https://github.com/vesoft-inc/nebula/pull/3316) [#3335](https://github.com/vesoft-inc/nebula/pull/3335) [#3328](https://github.com/vesoft-inc/nebula/pull/3328) [#3286](https://github.com/vesoft-inc/nebula/pull/3286) + +- 禁用`YIELD`子句返回自定义变量。 [#3271](https://github.com/vesoft-inc/nebula/pull/3271) + +- `FETCH`、`GO`、`LOOKUP`、`FIND PATH`、`GET SUBGRAPH`语句中必须添加`YIELD`子句。[#2957](https://github.com/vesoft-inc/nebula/pull/2957) [#3056](https://github.com/vesoft-inc/nebula/pull/3056) [#3139](https://github.com/vesoft-inc/nebula/pull/3139) + +- 新增非保留关键字`s2_max_level`、`s2_max_cells`。[#3396](https://github.com/vesoft-inc/nebula/pull/3396) + +- MATCH 语句中获取点属性时,必须指定 Tag,例如从`return v.name`变为`return v.player.name`。[#3255](https://github.com/vesoft-inc/nebula/pull/3255) ## 历史版本 diff --git a/docs-2.0/20.appendix/write-tools.md b/docs-2.0/20.appendix/write-tools.md index 80d3712a7c4..279a1f3310a 100644 --- a/docs-2.0/20.appendix/write-tools.md +++ b/docs-2.0/20.appendix/write-tools.md @@ -4,8 +4,8 @@ - 使用[命令行 -f 的方式](../2.quick-start/3.connect-to-nebula-graph.md)导入:可以导入少量准备好的 nGQL 文件,适合少量手工测试数据准备; - 使用 [studio 导入](../nebula-studio/quick-start/st-ug-import-data.md):可以用过浏览器导入本机多个 csv 文件,单个文件不超过 100 MB,格式有限制; -- 使用 [importer 导入](../nebula-importer/use-importer.md):导入单机多个 csv 文件,大小没有限制,格式灵活; -- 使用 [Exchange 导入](../nebula-exchange/about-exchange/ex-ug-what-is-exchange.md):从 Neo4j, Hive, MySQL 等多种源分布式导入,需要有 Spark 集群; +- 使用 [importer 导入](../nebula-importer/use-importer.md):导入单机多个 csv 文件,大小没有限制,格式灵活;数据量十亿级以内; +- 使用 [Exchange 导入](../nebula-exchange/about-exchange/ex-ug-what-is-exchange.md):从 Neo4j, Hive, MySQL 等多种源分布式导入,需要有 Spark 集群;数据量十亿级以上 - 使用 [Spark-connector](../nebula-spark-connector.md)/[Flink-connector](../nebula-flink-connector.md) 导入:有相应组件 (Spark/Flink),撰写少量代码; - 使用 [C++/GO/Java/Python SDK](../20.appendix/6.eco-tool-version.md):编写程序的方式导入,需要有一定编程和调优能力。 diff --git a/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md b/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md index 22b9ded1710..e6f24054026 100644 --- a/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md +++ b/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md @@ -2,7 +2,7 @@ nGQL(Nebula Graph Query Language)是 Nebula Graph 使用的的声明式图查询语言,支持灵活高效的[图模式](3.graph-patterns.md),而且 nGQL 是为开发和运维人员设计的类 SQL 查询语言,易于学习。 -nGQL 是一个进行中的项目,会持续发布新特性和优化,因此可能会出现语法和实际操作不一致的问题,如果遇到此类问题,请提交 [issue](https://github.com/vesoft-inc/nebula/issues) 通知 Nebula Graph 团队。Nebula Graph 2.0 及更新版本正在支持 [openCypher 9](https://www.opencypher.org/resources)。 +nGQL 是一个进行中的项目,会持续发布新特性和优化,因此可能会出现语法和实际操作不一致的问题,如果遇到此类问题,请提交 [issue](https://github.com/vesoft-inc/nebula/issues) 通知 Nebula Graph 团队。Nebula Graph 3.0 及更新版本正在支持 [openCypher 9](https://www.opencypher.org/resources)。 ## nGQL 可以做什么 @@ -26,6 +26,11 @@ nGQL 是一个进行中的项目,会持续发布新特性和优化,因此可 用户可以下载 Nebula Graph 示例数据 [basketballplayer 文件](https://docs.nebula-graph.io/2.0/basketballplayer-2.X.ngql),然后使用 [Nebula Graph Console](../../2.quick-start/3.connect-to-nebula-graph.md),使用选项`-f`执行脚本。 +!!! note + + 导入示例数据前,确保已执行`ADD HOSTS`命令将 Storage 主机增加至集群中。更多信息,请参见[管理 Storage 主机](../../4.deployment-and-installation/manage-storage-host.md)。 + + ## 占位标识符和占位符值 Nebula Graph 查询语言 nGQL 参照以下标准设计: diff --git a/docs-2.0/3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md b/docs-2.0/3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md index 0b92c71de5b..43b00323538 100644 --- a/docs-2.0/3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md +++ b/docs-2.0/3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md @@ -1,8 +1,12 @@ # 关键字 -关键字在 nGQL 中有重要意义,分为保留关键字和非保留关键字。 +关键字在 nGQL 中有重要意义,分为保留关键字和非保留关键字。建议不要在 Schema 中使用关键字。 -非保留关键字作为标识符时可以不使用引号。保留关键字或特殊字符作为标识符时,需要用反引号(\`)包围,例如 \`AND\`。 +如果必须使用关键字: + +- 非保留关键字作为标识符时可以不使用引号。 + +- 保留关键字或特殊字符作为标识符时,需要用反引号(\`)包围,例如 \`AND\`。 !!! Note diff --git a/docs-2.0/3.ngql-guide/10.tag-statements/3.alter-tag.md b/docs-2.0/3.ngql-guide/10.tag-statements/3.alter-tag.md index ee55d93f313..f76edd8de08 100644 --- a/docs-2.0/3.ngql-guide/10.tag-statements/3.alter-tag.md +++ b/docs-2.0/3.ngql-guide/10.tag-statements/3.alter-tag.md @@ -17,9 +17,9 @@ ALTER TAG [COMMENT = '']; alter_definition: -| ADD (prop_name data_type) +| ADD (prop_name data_type [NULL | NOT NULL] [DEFAULT ] [COMMENT '']) | DROP (prop_name) -| CHANGE (prop_name data_type) +| CHANGE (prop_name data_type [NULL | NOT NULL] [DEFAULT ] [COMMENT '']) ttl_definition: TTL_DURATION = ttl_duration, TTL_COL = prop_name @@ -36,6 +36,7 @@ nebula> CREATE TAG IF NOT EXISTS t1 (p1 string, p2 int); nebula> ALTER TAG t1 ADD (p3 int, p4 string); nebula> ALTER TAG t1 TTL_DURATION = 2, TTL_COL = "p2"; nebula> ALTER TAG t1 COMMENT = 'test1'; +nebula> ALTER TAG t1 ADD (p5 double NOT NULL DEFAULT 0.4 COMMENT 'p5') COMMENT='test2'; ``` ## 修改 Tag 说明 diff --git a/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md b/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md index 4cbee2a4296..07440d380df 100644 --- a/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md +++ b/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md @@ -36,7 +36,7 @@ 索引并不用于查询加速。只用于:根据属性定位到点或边,或者统计点边数量。 - 长索引会降低 Storage 服务的扫描性能,以及占用更多内存。建议将索引长度设置为和要被索引的最长字符串相同。索引长度最长为 255,超过部分会被截断。 + 长索引会降低 Storage 服务的扫描性能,以及占用更多内存。建议将索引长度设置为和要被索引的最长字符串相同。索引长度最长为 256。 如果必须使用索引,通常按照如下步骤: @@ -63,7 +63,7 @@ ## 语法 ```ngql -CREATE {TAG | EDGE} INDEX [IF NOT EXISTS] ON { | } ([]) [COMMENT = '']; +CREATE {TAG | EDGE} INDEX [IF NOT EXISTS] ON { | } ([]) [COMMENT '']; ``` |参数|说明| diff --git a/docs-2.0/3.ngql-guide/15.full-text-index-statements/1.search-with-text-based-index.md b/docs-2.0/3.ngql-guide/15.full-text-index-statements/1.search-with-text-based-index.md index 9f68ce88cc2..9b4bf225e92 100644 --- a/docs-2.0/3.ngql-guide/15.full-text-index-statements/1.search-with-text-based-index.md +++ b/docs-2.0/3.ngql-guide/15.full-text-index-statements/1.search-with-text-based-index.md @@ -77,7 +77,7 @@ LOOKUP ON { | } WHERE [YIELD ]; nebula> CREATE SPACE IF NOT EXISTS basketballplayer (partition_num=3,replica_factor=1, vid_type=fixed_string(30)); //登录文本搜索客户端。 -nebula> SIGN IN TEXT SERVICE (127.0.0.1:9200); +nebula> SIGN IN TEXT SERVICE (127.0.0.1:9200, HTTP); //切换图空间。 nebula> USE basketballplayer; diff --git a/docs-2.0/3.ngql-guide/5.operators/2.boolean.md b/docs-2.0/3.ngql-guide/5.operators/2.boolean.md index d56cf29645a..af88e036346 100644 --- a/docs-2.0/3.ngql-guide/5.operators/2.boolean.md +++ b/docs-2.0/3.ngql-guide/5.operators/2.boolean.md @@ -13,6 +13,6 @@ Nebula Graph 支持的布尔符如下。 对于带有`NULL`的逻辑运算,请参见 [NULL](../3.data-types/5.null.md)。 -## 历史兼容问题 +!!! note -非 0 数字不能转换为布尔值。 + 非 0 数字不能转换为布尔值。 diff --git a/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md b/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md index 398c1fa99dc..9973269814b 100644 --- a/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md +++ b/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md @@ -28,14 +28,18 @@ MATCH [] RETURN []; 除以下三种情况之外,请确保 `MATCH` 语句有**至少**一个[索引](../14.native-index-statements/1.create-native-index.md)可用。 -- A: `MATCH`语句中`WHERE`子句使用 id() 函数指定了点的 VID,不需要创建索引即可执行。 +- `MATCH`语句中`WHERE`子句使用 id() 函数指定了点的 VID,不需要创建索引即可执行。 -- B1: 当遍历所有点边时,例如`MATCH (v) RETURN v LIMIT N`,不需要创建索引,但必须使用`LIMIT`限制输出结果数量。 +- 当遍历所有点边时,例如`MATCH (v) RETURN v LIMIT N`,不需要创建索引,但必须使用`LIMIT`限制输出结果数量。 -- B2: 当遍历指定 Tag 的点或指定 Edge Type 的边时,例如`MATCH (v:player) RETURN v LIMIT N`,不需要创建索引,但必须使用`LIMIT`限制输出结果数量。 +- 当遍历指定 Tag 的点或指定 Edge Type 的边时,例如`MATCH (v:player) RETURN v LIMIT N`,不需要创建索引,但必须使用`LIMIT`限制输出结果数量。 此外`MATCH`语句中的`WHERE`子句内**不支持**图模式。 +!!! note + + 目前 match 语句无法查询到悬挂边。 + !!! compatibility "历史版本兼容性" 从 3.0.0 版本开始,为了区别不同 Tag 的属性,返回属性时必须额外指定 Tag 名称。即从`RETURN <变量名>.<属性名>`改为`RETURN <变量名>..<属性名>`。 diff --git a/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md b/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md index 13779202d19..3d50ac38cb3 100644 --- a/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md +++ b/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md @@ -54,7 +54,7 @@ YIELD [AS ]; - `$-`和`$^`。 - 在关系表达式中,不支持运算符两边都有字段名,例如`tagName.prop1 > tagName.prop2`。 - 不支持运算表达式和函数表达式中嵌套 AliasProp 表达式。 -- 不支持 XOR 和 NOT 运算符。 +- 不支持 XOR 运算符。 - 不支持除`STARTS WITH`之外的字符串操作。 - 不支持图模式。 diff --git a/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md b/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md index e332ea56884..12dac2e3c6e 100644 --- a/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md +++ b/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md @@ -94,9 +94,11 @@ 默认情况下,身份认证功能是关闭的,只能使用已存在的用户名(默认为`root`)和任意密码登录。如果想使用身份认证,请参见[身份认证](../../7.data-security/1.authentication/1.authentication.md)。 - 3. 执行如下命令检查`nebula-storaged`进程状态。 + 3. 执行如下命令将 `nebula-storaged` 进程增加为可用状态。 ```bash + nebula> ADD HOSTS "storaged0":9779,"storaged1":9779,"storaged2":9779; + nebula> SHOW HOSTS; +-------------+------+----------+--------------+----------------------+------------------------+---------+ | Host | Port | Status | Leader count | Leader distribution | Partition distribution | Version | @@ -106,8 +108,10 @@ | "storaged2" | 9779 | "ONLINE" | 0 | "No valid partition" | "No valid partition" | "3.0.0" | +-------------+------+----------+--------------+----------------------+------------------------+---------+ ``` + !!! Note + 从 3.0 开始,上报到 metad 的 `nebula-storaged` 服务需要人为 `ADD HOSTS` 之后才可以被使用。 -5. 执行两次`exit` 可以退出容器。 +5. 执行两次`exit`可以退出容器。 ## 查看 Nebula Graph 服务的状态和端口 @@ -273,4 +277,4 @@ docker pull vesoft/nebula-console:{{console.branch}} [使用 docker compose 部署 Nebula Graph 2.0 和 Web Studio](https://www.bilibili.com/video/BV1T54y1b7pa)(18 分 10 秒) ---> \ No newline at end of file +--> diff --git a/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-latest.md b/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-latest.md index 9120e851473..55731f15ec3 100644 --- a/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-latest.md +++ b/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-latest.md @@ -20,7 +20,7 @@ - 必须在原服务器上原地升级,不能修改原机器的 IP 地址、配置文件,不可更改集群拓扑。 -- 硬盘空间要求:各机器硬盘剩余空间都需要是原数据目录的**三倍以上**。 +- 硬盘空间要求:各机器硬盘剩余空间都需要是原数据目录的**三倍**。 - 已知会造成数据丢失的 4 种场景,和 alter schema 以及 default value 相关,参见 [github known issues](https://github.com/vesoft-inc/nebula-graph/issues/857)。 @@ -67,6 +67,9 @@ - 根据 Storage 和 Meta 服务配置中`data_path`参数的值找到数据文件的位置,并备份数据。默认路径为`nebula/data/storage`和`nebula/data/meta`。 + !!! danger + 升级时不会自动备份原有数据。务必手动备份数据,防止丢失。 + - 备份配置文件。 - 统计所有图空间升级前的数据量,供升级后比较。统计方法如下: @@ -117,8 +120,8 @@ 5. 使用`bin`目录下的新版 db_upgrader 文件升级数据格式。 - !!! caution - 本步骤会备份 Storage 服务中保存的数据,但为防止备份失败,升级数据格式前,务必按照本文**升级准备**部分的说明备份数据。 + !!! danger + 本步骤不会备份 Storage 服务中保存的数据。升级数据格式前,务必按照本文**升级准备**部分的说明备份数据。 命令语法: @@ -131,7 +134,7 @@ ``` - `old_storage_data_path`代表数据的存储路径,由 Storage 服务配置文件中的`data_path`参数定义。 - - `data_backup_path`代表自定义的数据备份路径。 + - `data_backup_path`代表自定义的数据备份路径。**当前版本该设置不生效,升级数据格式时不会将原有数据备份到任何路径。** - `meta_server_ip`和`port`分别代表 Meta 服务各节点的 IP 地址和端口号。 - `2:3`代表从 Nebula Graph 2.x 版本升级到 3.x 版本。 diff --git a/docs-2.0/4.deployment-and-installation/6.deploy-text-based-index/2.deploy-es.md b/docs-2.0/4.deployment-and-installation/6.deploy-text-based-index/2.deploy-es.md index 569c637d32b..ffba8f8d37e 100644 --- a/docs-2.0/4.deployment-and-installation/6.deploy-text-based-index/2.deploy-es.md +++ b/docs-2.0/4.deployment-and-installation/6.deploy-text-based-index/2.deploy-es.md @@ -77,13 +77,13 @@ curl -H "Content-Type: application/json; charset=utf-8" -XPUT http://127.0.0.1:9 ### 语法 ```ngql -SIGN IN TEXT SERVICE [( [,"", ""]), (), ...]; +SIGN IN TEXT SERVICE (, {HTTP | HTTPS} [,"", ""]) [, (, ...)]; ``` ### 示例 ```ngql -nebula> SIGN IN TEXT SERVICE (127.0.0.1:9200); +nebula> SIGN IN TEXT SERVICE (127.0.0.1:9200, HTTP); ``` !!! Note diff --git a/docs-2.0/4.deployment-and-installation/manage-storage-host.md b/docs-2.0/4.deployment-and-installation/manage-storage-host.md index fcfa1e0929c..b4ca21ce9d2 100644 --- a/docs-2.0/4.deployment-and-installation/manage-storage-host.md +++ b/docs-2.0/4.deployment-and-installation/manage-storage-host.md @@ -10,6 +10,10 @@ ADD HOSTS : [,: ...]; ``` +!!! note + + 增加 Storage 主机在**下一个**心跳周期之后才能生效,为确保数据同步,请等待 2 个心跳周期(20 秒),然后执行`SHOW HOSTS`查看是否在线。 + ## 删除 Storage 主机 从集群中删除 Storage 主机。 diff --git a/docs-2.0/5.configurations-and-logs/1.configurations/6.kernel-config.md b/docs-2.0/5.configurations-and-logs/1.configurations/6.kernel-config.md index d1c9a3774aa..20d831c9e70 100644 --- a/docs-2.0/5.configurations-and-logs/1.configurations/6.kernel-config.md +++ b/docs-2.0/5.configurations-and-logs/1.configurations/6.kernel-config.md @@ -39,7 +39,7 @@ ulimit -n 130000 ### vm.min_free_kbytes -`vm.min_free_kbytes`用于设置 Linux 虚拟机保留的最小空闲千字节数。如果系统内存足够,建议设置较大值。例如物理内存为 128 GB,可以将`vm.min_free_kbytes`设置为 5 GB。如果值太小,会导致系统无法申请足够的连续物理内存。 +`vm.min_free_kbytes`用于设置 Linux 内核保留的最小空闲千字节数。如果系统内存足够,建议设置较大值。例如物理内存为 128 GB,可以将`vm.min_free_kbytes`设置为 5 GB。如果值太小,会导致系统无法申请足够的连续物理内存。 ### vm.max_map_count diff --git a/docs-2.0/7.data-security/1.authentication/3.role-list.md b/docs-2.0/7.data-security/1.authentication/3.role-list.md index 8dcbd3ea43a..f0260df0142 100644 --- a/docs-2.0/7.data-security/1.authentication/3.role-list.md +++ b/docs-2.0/7.data-security/1.authentication/3.role-list.md @@ -64,10 +64,10 @@ Nebula Graph 内置了多种角色,说明如下: |Read data|Y|Y|Y|Y|Y|`GO`、`SET`、`PIPE`、`MATCH`、`ASSIGNMENT`、`LOOKUP`、`YIELD`、`ORDER BY`、`FETCH VERTICES`、`Find`、`FETCH EDGES`、`FIND PATH`、`LIMIT`、`GROUP BY`、`RETURN`| |Write data|Y|Y|Y|Y||`INSERT VERTEX`、`UPDATE VERTEX`、`INSERT EDGE`、`UPDATE EDGE`、`DELETE VERTEX`、`DELETE EDGES`、`DELETE TAG`| |Show operations|Y|Y|Y|Y|Y|`SHOW`、`CHANGE PASSWORD`| - |Job|Y|Y|Y|Y||`SUBMIT JOB COMPACT`、`SUBMIT JOB FLUSH`、`SUBMIT JOB STATS`、`STOP JOB`、`RECOVER JOB`| - |Write space|Y|||||`CREATE SPACE`、`DROP SPACE`、`CREATE SNAPSHOT`、`DROP SNAPSHOT`、`BALANCE`、`ADMIN`、`CONFIG`、`INGEST`、`DOWNLOAD`、`BUILD TAG INDEX`、`BUILD EDGE INDEX`| + |Job|Y|Y|Y|Y||`SUBMIT JOB COMPACT`、`SUBMIT JOB FLUSH`、`SUBMIT JOB STATS`、`STOP JOB`、`RECOVER JOB`、`BUILD TAG INDEX`、`BUILD EDGE INDEX`| + |Write space|Y|||||`CREATE SPACE`、`DROP SPACE`、`CREATE SNAPSHOT`、`DROP SNAPSHOT`、`BALANCE`、`ADMIN`、`CONFIG`、`INGEST`、`DOWNLOAD`| !!! caution diff --git a/docs-2.0/nebula-analytics.md b/docs-2.0/nebula-analytics.md index 2f4d461261a..89c5d8d288f 100644 --- a/docs-2.0/nebula-analytics.md +++ b/docs-2.0/nebula-analytics.md @@ -57,7 +57,7 @@ sudo rpm -i nebula-analytics-1.0.0-centos.x86_64.rpm --prefix /home/xxx/nebula- 1. 克隆仓库`analytics`。 ```bash - $ git clone -b {{analytics.branch}} https://github.com/vesoft-inc/nebula-analytics.git + $ git clone -b {{plato.branch}} https://github.com/vesoft-inc/nebula-analytics.git ``` 2. 进入目录`nebula-analytics`。 diff --git a/docs-2.0/nebula-br/1.what-is-br.md b/docs-2.0/nebula-br/1.what-is-br.md index f9adaf90762..5723c041f84 100644 --- a/docs-2.0/nebula-br/1.what-is-br.md +++ b/docs-2.0/nebula-br/1.what-is-br.md @@ -15,6 +15,7 @@ Backup&Restore(简称 BR)是一款命令行界面(CLI)工具,可以帮 - Nebula Graph 版本需要为 v{{ nebula.release }}。 - 数据备份仅支持全量备份,不支持增量备份。 +- 仅支持单 metad 部署的本地文件的自动部署和恢复。 - Nebula Listener 暂时不支持备份,且全文索引也不支持备份。 - 如果备份数据到本地磁盘,备份的文件将会放置在每个服务器的本地路径中。也可以在本地挂载 NFS 文件系统,以便将备份数据还原到不同的主机上。 - 备份图空间只能恢复到原集群,不能跨集群恢复。 @@ -124,3 +125,9 @@ Backup&Restore(简称 BR)是一款命令行界面(CLI)工具,可以帮 1. [编译 BR](2.compile-br.md) 2. [使用 BR 备份数据](3.br-backup-data.md) 3. [使用 BR 恢复数据](4.br-restore-data.md) + +## 视频 + +- [Nebula Graph 容灾备份工具 nebula-br 介绍](https://www.bilibili.com/video/av851858570)(3 分 34 秒) + + \ No newline at end of file diff --git a/docs-2.0/nebula-br/4.br-restore-data.md b/docs-2.0/nebula-br/4.br-restore-data.md index 74d3ba187dc..d7a44df40f2 100644 --- a/docs-2.0/nebula-br/4.br-restore-data.md +++ b/docs-2.0/nebula-br/4.br-restore-data.md @@ -70,7 +70,7 @@ 或者使用以下命令,将兼容 s3 协议的对象存储服务 `br-test` 桶下的`backup`的备份,恢复到 meta 服务的地址为`127.0.0.1:9559`的集群中。 ```bash - br restore full --meta "127.0.0.1:9559" --s3.endpoint "http://127.0.0.1:9000" --storage="s3://br-test/backup/" --s3.access_key=minioadmin --s3.secret_key=minioadmin --s3.region="default" --name BACKUP_2021_12_08_18_38_08 + $ ./bin/br restore full --meta "127.0.0.1:9559" --s3.endpoint "http://127.0.0.1:9000" --storage="s3://br-test/backup/" --s3.access_key=minioadmin --s3.secret_key=minioadmin --s3.region="default" --name BACKUP_2021_12_08_18_38_08 ``` 如果返回如下信息,表示数据已经恢复成功。 diff --git a/docs-2.0/nebula-dashboard-ent/8.faq.md b/docs-2.0/nebula-dashboard-ent/8.faq.md index ac41bda800f..28752d1cdca 100644 --- a/docs-2.0/nebula-dashboard-ent/8.faq.md +++ b/docs-2.0/nebula-dashboard-ent/8.faq.md @@ -20,9 +20,9 @@ 由于集群的管理操作需要获取对应节点的 SSH 信息,因此 Dashboard 在执行操作前,需要先拥有最少可执行权限的 SSH 账号密码信息。 -## 什么是扩缩容? + ## 为什么不能操作 Meta 服务? diff --git a/docs-2.0/nebula-dashboard/2.deploy-dashboard.md b/docs-2.0/nebula-dashboard/2.deploy-dashboard.md index 8d27704010e..7bd5210392c 100644 --- a/docs-2.0/nebula-dashboard/2.deploy-dashboard.md +++ b/docs-2.0/nebula-dashboard/2.deploy-dashboard.md @@ -133,12 +133,12 @@ $ nohup ./node-exporter --web.listen-address=":9100" & - job_name: 'nebula-stats-exporter' static_configs: - targets: [ - '192.168.xx.100:9200' # nebula-stats-exporter 服务的 IP 地址和端口。 + '192.168.xx.100:9200' # nebula-stats-exporter 服务的 IP 地址和端口。 ] - job_name: 'node-exporter' static_configs: - targets: [ - '192.168.xx.100:9100', # node-exporter 服务的 IP 地址和端口。 + '192.168.xx.100:9100', # node-exporter 服务的 IP 地址和端口。 '192.168.xx.101:9100' ] ``` diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-clickhouse.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-clickhouse.md index 2a54e20639d..517f36651b4 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-clickhouse.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-clickhouse.md @@ -97,7 +97,7 @@ cores: 1 maxResultSize: 1G } - cores { + cores: { max: 16 } } @@ -116,11 +116,11 @@ pswd: nebula # 填写 Nebula Graph 中需要写入数据的图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-csv.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-csv.md index d16c1efe27f..ed64e53504b 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-csv.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-csv.md @@ -115,7 +115,7 @@ memory:1G } - cores { + cores: { max: 16 } } @@ -136,11 +136,11 @@ # 指定图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hbase.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hbase.md index 116bd36989e..c69b029932e 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hbase.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hbase.md @@ -134,7 +134,7 @@ ROW COLUMN+CELL cores: 1 maxResultSize: 1G } - cores { + cores: { max: 16 } } @@ -153,11 +153,11 @@ ROW COLUMN+CELL pswd: nebula # 填写 Nebula Graph 中需要写入数据的图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hive.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hive.md index fd3daa7ace1..197aff44798 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hive.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-hive.md @@ -165,7 +165,7 @@ scala> sql("select playerid, teamid, start_year, end_year from basketball.serve" cores: 1 maxResultSize: 1G } - cores { + cores: { max: 16 } } @@ -193,11 +193,11 @@ scala> sql("select playerid, teamid, start_year, end_year from basketball.serve" pswd: nebula # 填写 Nebula Graph 中需要写入数据的图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-json.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-json.md index e6d4d98e754..ffdeb1dd78f 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-json.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-json.md @@ -143,7 +143,7 @@ memory:1G } - cores { + cores: { max: 16 } } @@ -164,11 +164,11 @@ # 指定图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md index 414afe2aa3e..339afc7855e 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md @@ -89,7 +89,7 @@ cores: 1 maxResultSize: 1G } - cores { + cores: { max: 16 } } @@ -108,11 +108,11 @@ pswd: nebula # 填写 Nebula Graph 中需要写入数据的图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-maxcompute.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-maxcompute.md index bb9c23ce1f0..12de03c6f47 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-maxcompute.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-maxcompute.md @@ -97,7 +97,7 @@ cores: 1 maxResultSize: 1G } - cores { + cores: { max: 16 } } @@ -116,11 +116,11 @@ pswd: nebula # 填写 Nebula Graph 中需要写入数据的图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-mysql.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-mysql.md index 16eac40e174..0ffe914e16d 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-mysql.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-mysql.md @@ -137,7 +137,7 @@ mysql> desc serve; cores: 1 maxResultSize: 1G } - cores { + cores: { max: 16 } } @@ -156,11 +156,11 @@ mysql> desc serve; pswd: nebula # 填写 Nebula Graph 中需要写入数据的图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-neo4j.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-neo4j.md index 1d1025ec5e9..78636b53d24 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-neo4j.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-neo4j.md @@ -141,12 +141,12 @@ Exchange 读取 Neo4j 数据时需要完成以下工作: pswd: nebula space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-orc.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-orc.md index eb97c8e2300..8d1c159d53b 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-orc.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-orc.md @@ -111,7 +111,7 @@ memory:1G } - cores { + cores: { max: 16 } } @@ -132,11 +132,11 @@ # 指定图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-parquet.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-parquet.md index 22d75de26d4..be6f3e388f7 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-parquet.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-parquet.md @@ -111,7 +111,7 @@ memory:1G } - cores { + cores: { max: 16 } } @@ -132,11 +132,11 @@ # 指定图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-pulsar.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-pulsar.md index a9de2e3fb74..34764d0ccae 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-pulsar.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-pulsar.md @@ -89,7 +89,7 @@ cores: 1 maxResultSize: 1G } - cores { + cores: { max: 16 } } @@ -108,11 +108,11 @@ pswd: nebula # 填写 Nebula Graph 中需要写入数据的图空间名称。 space: basketballplayer - connection { + connection: { timeout: 3000 retry: 3 } - execution { + execution: { retry: 3 } error: { diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md index 78742300789..8be04ce251b 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md @@ -212,7 +212,7 @@ SST 文件是一个内部包含了任意长度的有序键值对集合的文件 } # 客户端连接参数 - connection { + connection: { # socket 连接、执行的超时时间,单位:毫秒。 timeout: 30000 } diff --git a/docs-2.0/nebula-explorer/canvas-operations/canvas-snapshot.md b/docs-2.0/nebula-explorer/canvas-operations/canvas-snapshot.md index 0d2916b6b54..53a4f82c02c 100644 --- a/docs-2.0/nebula-explorer/canvas-operations/canvas-snapshot.md +++ b/docs-2.0/nebula-explorer/canvas-operations/canvas-snapshot.md @@ -23,7 +23,7 @@ Explorer 的快照功能可保存图探索得到的可视化结果,以便再 - 单击![snapshot_export](../figs/snapshot-export.png)以 JSON 的格式下载历史快照至本地。 - 单击![snapshot_delete](../figs/snapshot-delete.png)删除历史快照。 -在历史快照列表左上方,单击**导入快照**可导入之前下载的 JSON 格式文件至快照列表中,以便用户之间离线共享快照数据。系统会根据 JONS 文件中记录的图空间信息将导入的快照自动放置于相应的图空间中。 +在历史快照列表左上方,单击**导入快照**可导入之前下载的 JSON 格式文件至快照列表中,以便用户之间离线共享快照数据。系统会根据 JSON 文件中记录的图空间信息将导入的快照自动放置于相应的图空间中。 !!! note diff --git a/docs-2.0/nebula-explorer/canvas-operations/visualization-mode.md b/docs-2.0/nebula-explorer/canvas-operations/visualization-mode.md index 08cd15c5cfb..1e8facfdc53 100644 --- a/docs-2.0/nebula-explorer/canvas-operations/visualization-mode.md +++ b/docs-2.0/nebula-explorer/canvas-operations/visualization-mode.md @@ -18,7 +18,7 @@ Explorer 支持 **2D** 和 **3D** 两种可视化模式探索数据。2D 模式 | ---------- | ------------------------------------------------------------ | | 出入度权重 | 根据画布中所有点的出边和入边的条数,自动调整点的大小。 | | 重置出入度 | 重置画布中的点至原始大小。 | -| 信息检测 | 孤立点:检测画布中所有的无边点。
悬挂边:检测画布中只有一条无向边的点。
环检测:检测由边和点连接在一起形成循环的路径。 | +| 信息检测 | 孤立点:检测画布中所有的无边点。
悬挂边:检测画布中与度数为1的点关联的边(包含关联点)。
环检测:检测由边和点连接在一起形成循环的路径。 | 有关更多的 2D 模式下可进行的操作,参见[画布功能](canvas-overview.md)。 diff --git a/docs-2.0/nebula-studio/about-studio/st-ug-terms.md b/docs-2.0/nebula-studio/about-studio/st-ug-terms.md index b69eaa56ddf..9cde6d2cfdf 100644 --- a/docs-2.0/nebula-studio/about-studio/st-ug-terms.md +++ b/docs-2.0/nebula-studio/about-studio/st-ug-terms.md @@ -6,4 +6,6 @@ - Nebula Graph:一款开源图数据库管理系统(Graph Database Management System),擅长处理千亿个点和万亿条边的超大规模数据集。详细信息,参考 [Nebula Graph 用户手册](../../README.md "点击前往 Nebula Graph 用户手册")。 + diff --git a/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md b/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md index e35e35f2c6b..91360848460 100644 --- a/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md +++ b/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md @@ -35,7 +35,9 @@ Studio 具备以下功能: ## 身份验证 + 因为 Nebula Graph 默认不启用身份验证,所以,一般情况下用户可以使用 `root` 账号和任意密码登录 Studio。 diff --git a/docs-2.0/reuse/source_connect-to-nebula-graph.md b/docs-2.0/reuse/source_connect-to-nebula-graph.md index d9145503847..7cb688d6e10 100644 --- a/docs-2.0/reuse/source_connect-to-nebula-graph.md +++ b/docs-2.0/reuse/source_connect-to-nebula-graph.md @@ -30,11 +30,8 @@ Nebula Graph 支持多种类型客户端,包括 CLI 客户端、GUI 客户端 建议选择**最新**版本。 - ![Select a Nebula Graph version and click **Assets**](../reuse/console260.png "Click Assets to show the available Nebula Graph binary files") - 2. 在** Assets **区域找到机器运行所需的二进制文件,下载文件到机器上。 - ![Click to download the package according to your hardware architecture](../reuse/assets260.png "Click the package name to download it") 3. (可选)为方便使用,重命名文件为`nebula-console`。 diff --git a/docs-2.0/reuse/source_manage-service.md b/docs-2.0/reuse/source_manage-service.md index 0ba792189d4..654adb866fc 100644 --- a/docs-2.0/reuse/source_manage-service.md +++ b/docs-2.0/reuse/source_manage-service.md @@ -124,9 +124,9 @@ $ sudo /usr/local/nebula/scripts/nebula.service status all - 如果返回如下结果,表示 Nebula Graph 服务正常运行。 ```bash - [INFO] nebula-metad(de03025): Running as 26601, Listening on 9559 - [INFO] nebula-graphd(de03025): Running as 26644, Listening on 9669 - [INFO] nebula-storaged(de03025): Running as 26709, Listening on 9779 + [INFO] nebula-metad(02b2091): Running as 26601, Listening on 9559 + [INFO] nebula-graphd(02b2091): Running as 26644, Listening on 9669 + [INFO] nebula-storaged(02b2091): Running as 26709, Listening on 9779 ``` - 如果返回类似如下结果,表示 Nebula Graph 服务异常,可以根据异常服务信息进一步排查,或者在 [Nebula Graph 社区](https://discuss.nebula-graph.com.cn/)寻求帮助。 diff --git a/mkdocs.yml b/mkdocs.yml index df42f26cfc4..bd33078e8d4 100755 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -43,13 +43,16 @@ extra_css: - css/version-select.css - stylesheets/extra.css extra: + analytics: + provider: google + property: UA-60523578-15 nebula: - release: master + release: 3.0.0 nightly: nightly master: master base20: 2.0 base200: 2.0.0 - branch: master + branch: v3.0.0 version: method: mike social: @@ -75,7 +78,7 @@ extra: algorithm: release: 3.0.0 branch: v3.0.0 - analytics: + plato: release: 1.0.0 branch: v1.0.0 sparkconnector: @@ -125,6 +128,9 @@ extra: nav: - 前言: README.md - 简介: + - 图: 1.introduction/0-0-graph.md + - 图数据库: 1.introduction/0-1-graph-database.md + - 相关技术: 1.introduction/0-2.relates.md - 什么是 Nebula Graph: 1.introduction/1.what-is-nebula-graph.md - 数据模型: 1.introduction/2.data-model.md - 路径: 1.introduction/2.1.path.md @@ -518,6 +524,7 @@ nav: - 生态工具概览: 20.appendix/6.eco-tool-version.md - 导入工具选择: 20.appendix/write-tools.md - 社区参与: 15.contribution/how-to-contribute.md + - 年表: 20.appendix/history.md - 思维导图: 20.appendix/mind-map.md - English Docs: https://docs.nebula-graph.io/ @@ -566,7 +573,7 @@ plugins: - with-pdf: copyright: 2022 vesoft Inc. - cover_subtitle: master sinnce 3.0.0 + cover_subtitle: master since 3.0.0 author: 吴敏,周瑶,梁振亚,杨怡璇,黄凤仙 cover: true back_cover: true @@ -580,7 +587,3 @@ extra_javascript: - js/init.js - https://polyfill.io/v3/polyfill.min.js?features=es6 - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js - -google_analytics: - - UA-60523578-15 - - auto diff --git a/requirements.txt b/requirements.txt index 89de7752c90..219bca05682 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,4 @@ weasyprint==52.5 mkdocs-with-pdf qrcode mkdocs-exclude +