{"action":"created","comment":{"url":"https://api.github.com/repos/vesoft-inc/nebula/pulls/comments/339407296","pull_request_review_id":307645866,"id":339407296,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDMzOTQwNzI5Ng==","diff_hunk":"@@ -1,2 +1,141 @@\n-<!-- TODO translate from CN -->\n-To be provided.\n\\ No newline at end of file\n+# Storage Design\n+\n+## Abstract\n+\n+This document is to give an introduction on the storage design of the graph database Nebula Graph.\n+\n+The Storage Service of nebula is composed of two parts, one is `Meta Service` that stores the meta data, the other is `Storage Service`that stores the data. The two services are in two independent processes. The data and deployment are separated as well. But their architectures are almost the same.\n+\n+## Architecture\n+\n+---\n+![image](https://user-images.githubusercontent.com/42762957/67537389-c26bf000-f70d-11e9-9f9d-013cff70209a.png)\n+\n+Pict.1 The Architecture of Storage Service\n+\n+---\n+\n+As shown in Picture One, there are three layers in Storage Service. The bottom layer is the local storage engine, providing `get`, `put`, `scan` and `delete` operations on local data. The related interfaces are in `KVStore/KVEngine.h` and users can develop their own local store plugins based on their needs. Currently, nebula provides store engine based on RocksDB.\n+\n+Above the local storage engine is the consensus layer that implements multi group raft. Each partition corresponding to a Raft group, is for the data sharding. Currently, nebula uses `hash` to shard data. When creating a space, users need to specify the partition number. Once set, partition number can not be changed. Generally, the partition number should meet the scale out needs in the future.\n+\n+Above the consensus layer is the storage interfaces that defines a set of APIs that are related with graph. These API requirements are translated into a set of kv operations targeting at the corresponding partition. It is this layer that makes the storage service a real graph storage, otherwise it's just a kv storage. Nebula doesn't separate kv as an independent service as graph query involves a lot of calculation that use schema, which is not existed in kv layer. Such architecture makes pushing down more easily.\n+\n+## Schema & Partition\n+\n+Nebula stores the vertices, edges and properties. Efficient property filtering is critical for a Graph Database.\n+\n+Nebula uses tags to indicate vertices types. One vertexID can relate with multiple tags, and each tag has its own properties. In kv storage, we use `vertexID + TagID` to represent key, and the related properties are placed behind value after encoding, the format is shown in Picture Two:\n+\n+---\n+![image](https://user-images.githubusercontent.com/42762957/67537434-f9420600-f70d-11e9-91f4-1359ef3c82b9.png)\n+\n+Pict.2 Vertex Key Format\n+\n+---\n+\n+- `Type`: one byte, used to indicate key type, current types are data, index, system, etc.\n+- `Part ID`: three bytes, used to indicate the sharding partition. This field can be used to **scan the partition data based on the prefix when re-balancing the partition**\n+- `Vertex ID`: four bytes, used to indicate vertex ID\n+- `Tag ID`: four bytes, used to relate tag\n+- `Timestamp`: eight bytes, not available to users, used in MVCC in the future\n+\n+Each edge in Nebula Graph is modeled as two independent key-values. One is stored in the same partition as the source vertex, namely out-edge. The other one is stored in the same partition as the destination vertex, namely in-edge. Generally, out-key and in-key are stored in different partitions.\n+\n+There may be multiple edge types or multiple edges with the same edge type between two vertices. For example, define an edge type 'transfer', user A may transfer money to user B multiple times, thus a field `rank` is added to distinguish the transfer records between the two. Edge key format shown as Picture Three:\n+\n+---\n+![image](https://user-images.githubusercontent.com/42762957/67537454-11b22080-f70e-11e9-9f9a-787091c60982.png)\n+\n+Pict.3 Edge Key Format\n+\n+---\n+\n+- `Type`: one byte, used to indicate key type, current types are data, index, system, etc.\n+- `Part ID`: three bytes, used to indicate the sharding partition. This field can be used to **scan the partition data based on the prefix when re-balancing the partition**\n+- `Vertex ID`: four bytes, used to indicate source vertex ID in out-edge, dest vertex ID in in-edge\n+- `Edge Type`: four bytes, used to indicate edge type, greater than zero means out-edge, less than zero means in-edge\n+- `Rank`: four bytes, used to indicate multiple edges in one edge type. Users can set the filed based on needs, it can store weight such as _transaction time_, _transaction number_ and _weight of a certain order_\n+- `Timestamp`: eight bytes, not available to users, used in MVCC in the future\n+\n+If the value of an edge type is greater than zero, the corresponding edge key format is shown in Picture Four; otherwise if the value less than zero, the corresponding edge key format is shown in Picture Five.\n+\n+---\n+![image](https://user-images.githubusercontent.com/42762957/67537498-3efece80-f70e-11e9-9d41-0af45cdff104.png)\n+\n+Pict.4 Out-key format\n+\n+---\n+\n+![image](https://user-images.githubusercontent.com/42762957/67537516-5047db00-f70e-11e9-9760-282b66c877f4.png)\n+\n+Pict.5 In-key format\n+\n+---\n+\n+The properties of vertices and edges are stored in the values of the corresponding kv pairs after encoding. As a strong typed database, Nebula needs get the schema information in the Meta Service before decoding. Besides, when encoding properties, schema version is added to support online schema change.\n+\n+Nebula shards data through `modulo operation` on vertex ID. All the _out-keys_, _in-keys_ and _tag data_ are placed in the same partition through `modulo operation` on vertex ID. In this way, query efficiency is increased dramatically. For on-line queries, the most common operation is to do Breadth-First-Search (BFS) expansion from a vertex, thus it's the basic operation to get a vertex's in-edge or out-edge, and such operation's performance determines the traverse's performance. In BFS, there are cases filtering on some properties, Nebula guarantees the operation efficiency by putting properties and vertices and edges together. At present, most graph databases verify their efficiency with Graph 500 or Twitter data set, which are, of no eloquence for properties are not included. While most cases use property graphs and BFS needs a lot of filtering as well.\n+\n+## KVStore\n+\n+Nebula develops its own kv store to meet the performance needs:\n+\n+- **High performance** pure kv\n+- **Provided as a library**, as a strong typed database, the performance of pushing down is the key of the performance of Nebula\n+- **Strong data consistency**, determined by the distribution system\n+- **Written in C++**  \n+\n+For users that are not sensitive to performance or unwilling to migrate data, Nebula provides plugins for the whole kv store, builds the storage service on the third party kv store. Currently, Nebula provides HBase plugin.\n+\n+With the RocksDB as the local storage engine, Nebula supports self management of multiple hard disks to take full use of the parallel property. All users need to do is to config multiple data directories.  Nebula manages the distributed kv store in a unified scheduling way with meta service. All the partition distribution data and current machine status can be found in the meta service. Users can input commands in the console to add or remove machines to generate and execute a balance plan in meta service.\n+\n+Nebula provides its own WAL mode to customize the WAL. Each partition owns its WAL to catch up data without WAL split to guarantee efficiency. Besides, Nebula defines a Command Log class to conduct special operations. These logs have no real data and only used to inform all replicas to execute certain operations with raft. What's more, Nebula also provides a log class to conduct atomic operation on partitions. For example, the CAS and the read-modify-write which fully uses raft serialization.\n+\n+One Nebula kv store cluster supports multiple spaces, and each space is set with its own partition number and replica number. Different spaces are isolated physically and spaces in the same clusters supports different storage engine and sharding strategy.\n+\n+## Raft\n+\n+This part gives some details on how raft works for Nebula.\n+\n+### Multi Raft Group\n+\n+As the log IDs must be serial, almost all the implementations adapt Multi Raft Group to solve this problem. Therefore, partition number almost determines the performance of the Raft Group,but it doesn't mean the more partitions, the better the performance. Each raft group stores a set of state information and has its own WAL file, thus more partitions requires more costs. Also, when there are too many Partitions, the batch operation is meaningless if the load is not high enough. For example, a single online system with 1w tps, if its partition number is greater than ten thousand, the tps of each partition per second is likely only 1, so the batch operation loses its meaning and increases CPU cost.\n+\n+There are two key points to achieve the Multi Raft Group. **The first is to share the transport layer**, because each Raft Group needs to send messages to the corresponding peers. If the transport layer cannot be shared, the connection costs are huge. **Second is the threading model**, multi Raft Group must share a set of thread pools, otherwise will end with too many threads in the system, resulting in a large amount of context switch cost.\n+\n+### Batch\n+\n+For each Partition, it is necessary to do batch to improve throughput when writing WAL serially. In general, there is nothing special about batch, but Nebula designs some special types of WAL based on each part serialization, which brings some challenges.\n+\n+For example, Nebula uses WAL to implement lock-free CAS operations, and each CAS operation will execute after all the previous WAL are committed . So for a batch, if there are several WALs in CAS type, we need to divide this batch into several smaller serial groups.\n+\n+### Learner\n+\n+New machines need to \"catch up\" data for quite a long time, and there may be accidents during the process. If a new machine join the raft group as a follower, it will reduce the HA capacity of the entire cluster. Nebula uses the command WAL mentioned above to implement its learner. If the leader encounters the add learner command when writing WAL, it will add the learner to its peers and mark it as learner, so even if leaner is not included when counting majority, logs will send to them as normal. Of course, learner will not start election automatically.\n+\n+### Transfer Leadership\n+\n+Transfer leadership is extremely important for balance. When moving a partition from one machine to another, Nebula first checks if the source is a leader. If so, it should be moved to another peer. After  data migration is completed, please balance the leader, so that the load on each machine can be balanced.\n+\n+When transferring leadership, note that when the leader abandons its leadership and when the follower starts a leader election. When a transfer leadership command is committed, the original leader abandons its leadership. And as for followers, when receiving the command, it starts a leader election. This is the same execution process with common raft leader election. Otherwise some corner cases will occur.\n+\n+### Membership change\n+\n+When member in a Raft Group changes, an intermediate state is required. In this state, the majority of the old group and  new group always have an overlap, thus preventing the old or new group from making decision. To make it even simpler, Diego Ongaro suggests **adding or removing a peer once to ensure the the overlap between the majority of the new group and the old group** in his doctoral thesis. Nebula's implementation also uses this approach, except that the way to add or remove member is different. Details please refer `addPeer/removePeer` in Raft Part class.","path":"docs/manual-EN/1.overview/3.design-and-architecture/2.storage-design.md","position":128,"original_position":128,"commit_id":"00dff8eb2d93d1493167347b8dbb836fb990b808","original_commit_id":"00dff8eb2d93d1493167347b8dbb836fb990b808","user":{"login":"whitewum","id":50101159,"node_id":"MDQ6VXNlcjUwMTAxMTU5","avatar_url":"https://avatars2.githubusercontent.com/u/50101159?v=4","gravatar_id":"","url":"https://api.github.com/users/whitewum","html_url":"https://github.com/whitewum","followers_url":"https://api.github.com/users/whitewum/followers","following_url":"https://api.github.com/users/whitewum/following{/other_user}","gists_url":"https://api.github.com/users/whitewum/gists{/gist_id}","starred_url":"https://api.github.com/users/whitewum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/whitewum/subscriptions","organizations_url":"https://api.github.com/users/whitewum/orgs","repos_url":"https://api.github.com/users/whitewum/repos","events_url":"https://api.github.com/users/whitewum/events{/privacy}","received_events_url":"https://api.github.com/users/whitewum/received_events","type":"User","site_admin":false},"body":"为了避免脑裂，当一个 Raft Group 的成员发生变化时，需要有一个中间状态， 这个状态下 old group 的多数派与 new group 的多数派总是有 overlap，这样就防止了 old group 或者新 group 单方面做出决定，这就是论文中提到的 joint consensus","created_at":"2019-10-28T05:35:32Z","updated_at":"2019-10-28T05:36:23Z","html_url":"https://github.com/vesoft-inc/nebula/pull/1138#discussion_r339407296","pull_request_url":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/vesoft-inc/nebula/pulls/comments/339407296"},"html":{"href":"https://github.com/vesoft-inc/nebula/pull/1138#discussion_r339407296"},"pull_request":{"href":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138"}}},"pull_request":{"url":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138","id":331454658,"node_id":"MDExOlB1bGxSZXF1ZXN0MzMxNDU0NjU4","html_url":"https://github.com/vesoft-inc/nebula/pull/1138","diff_url":"https://github.com/vesoft-inc/nebula/pull/1138.diff","patch_url":"https://github.com/vesoft-inc/nebula/pull/1138.patch","issue_url":"https://api.github.com/repos/vesoft-inc/nebula/issues/1138","number":1138,"state":"open","locked":false,"title":"[doc]storage-design-EN","user":{"login":"Amber1990Zhang","id":42762957,"node_id":"MDQ6VXNlcjQyNzYyOTU3","avatar_url":"https://avatars0.githubusercontent.com/u/42762957?v=4","gravatar_id":"","url":"https://api.github.com/users/Amber1990Zhang","html_url":"https://github.com/Amber1990Zhang","followers_url":"https://api.github.com/users/Amber1990Zhang/followers","following_url":"https://api.github.com/users/Amber1990Zhang/following{/other_user}","gists_url":"https://api.github.com/users/Amber1990Zhang/gists{/gist_id}","starred_url":"https://api.github.com/users/Amber1990Zhang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Amber1990Zhang/subscriptions","organizations_url":"https://api.github.com/users/Amber1990Zhang/orgs","repos_url":"https://api.github.com/users/Amber1990Zhang/repos","events_url":"https://api.github.com/users/Amber1990Zhang/events{/privacy}","received_events_url":"https://api.github.com/users/Amber1990Zhang/received_events","type":"User","site_admin":false},"body":"as title \r\ntranslating from\r\n\r\nhttps://github.com/vesoft-inc/nebula/blob/master/docs/manual-CN/1.overview/3.design-and-architecture/2.storage-design.md","created_at":"2019-10-23T10:05:37Z","updated_at":"2019-10-28T05:36:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0dcdf2f1052cf19e75df94ff2690f50595f56fbf","assignee":null,"assignees":[],"requested_reviewers":[{"login":"darionyaphet","id":4414314,"node_id":"MDQ6VXNlcjQ0MTQzMTQ=","avatar_url":"https://avatars2.githubusercontent.com/u/4414314?v=4","gravatar_id":"","url":"https://api.github.com/users/darionyaphet","html_url":"https://github.com/darionyaphet","followers_url":"https://api.github.com/users/darionyaphet/followers","following_url":"https://api.github.com/users/darionyaphet/following{/other_user}","gists_url":"https://api.github.com/users/darionyaphet/gists{/gist_id}","starred_url":"https://api.github.com/users/darionyaphet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/darionyaphet/subscriptions","organizations_url":"https://api.github.com/users/darionyaphet/orgs","repos_url":"https://api.github.com/users/darionyaphet/repos","events_url":"https://api.github.com/users/darionyaphet/events{/privacy}","received_events_url":"https://api.github.com/users/darionyaphet/received_events","type":"User","site_admin":false},{"login":"critical27","id":13706157,"node_id":"MDQ6VXNlcjEzNzA2MTU3","avatar_url":"https://avatars3.githubusercontent.com/u/13706157?v=4","gravatar_id":"","url":"https://api.github.com/users/critical27","html_url":"https://github.com/critical27","followers_url":"https://api.github.com/users/critical27/followers","following_url":"https://api.github.com/users/critical27/following{/other_user}","gists_url":"https://api.github.com/users/critical27/gists{/gist_id}","starred_url":"https://api.github.com/users/critical27/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/critical27/subscriptions","organizations_url":"https://api.github.com/users/critical27/orgs","repos_url":"https://api.github.com/users/critical27/repos","events_url":"https://api.github.com/users/critical27/events{/privacy}","received_events_url":"https://api.github.com/users/critical27/received_events","type":"User","site_admin":false},{"login":"dangleptr","id":37216992,"node_id":"MDQ6VXNlcjM3MjE2OTky","avatar_url":"https://avatars1.githubusercontent.com/u/37216992?v=4","gravatar_id":"","url":"https://api.github.com/users/dangleptr","html_url":"https://github.com/dangleptr","followers_url":"https://api.github.com/users/dangleptr/followers","following_url":"https://api.github.com/users/dangleptr/following{/other_user}","gists_url":"https://api.github.com/users/dangleptr/gists{/gist_id}","starred_url":"https://api.github.com/users/dangleptr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dangleptr/subscriptions","organizations_url":"https://api.github.com/users/dangleptr/orgs","repos_url":"https://api.github.com/users/dangleptr/repos","events_url":"https://api.github.com/users/dangleptr/events{/privacy}","received_events_url":"https://api.github.com/users/dangleptr/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138/commits","review_comments_url":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138/comments","review_comment_url":"https://api.github.com/repos/vesoft-inc/nebula/pulls/comments{/number}","comments_url":"https://api.github.com/repos/vesoft-inc/nebula/issues/1138/comments","statuses_url":"https://api.github.com/repos/vesoft-inc/nebula/statuses/00dff8eb2d93d1493167347b8dbb836fb990b808","head":{"label":"Amber1990Zhang:storage-design-EN","ref":"storage-design-EN","sha":"00dff8eb2d93d1493167347b8dbb836fb990b808","user":{"login":"Amber1990Zhang","id":42762957,"node_id":"MDQ6VXNlcjQyNzYyOTU3","avatar_url":"https://avatars0.githubusercontent.com/u/42762957?v=4","gravatar_id":"","url":"https://api.github.com/users/Amber1990Zhang","html_url":"https://github.com/Amber1990Zhang","followers_url":"https://api.github.com/users/Amber1990Zhang/followers","following_url":"https://api.github.com/users/Amber1990Zhang/following{/other_user}","gists_url":"https://api.github.com/users/Amber1990Zhang/gists{/gist_id}","starred_url":"https://api.github.com/users/Amber1990Zhang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Amber1990Zhang/subscriptions","organizations_url":"https://api.github.com/users/Amber1990Zhang/orgs","repos_url":"https://api.github.com/users/Amber1990Zhang/repos","events_url":"https://api.github.com/users/Amber1990Zhang/events{/privacy}","received_events_url":"https://api.github.com/users/Amber1990Zhang/received_events","type":"User","site_admin":false},"repo":{"id":186778335,"node_id":"MDEwOlJlcG9zaXRvcnkxODY3NzgzMzU=","name":"nebula","full_name":"Amber1990Zhang/nebula","private":false,"owner":{"login":"Amber1990Zhang","id":42762957,"node_id":"MDQ6VXNlcjQyNzYyOTU3","avatar_url":"https://avatars0.githubusercontent.com/u/42762957?v=4","gravatar_id":"","url":"https://api.github.com/users/Amber1990Zhang","html_url":"https://github.com/Amber1990Zhang","followers_url":"https://api.github.com/users/Amber1990Zhang/followers","following_url":"https://api.github.com/users/Amber1990Zhang/following{/other_user}","gists_url":"https://api.github.com/users/Amber1990Zhang/gists{/gist_id}","starred_url":"https://api.github.com/users/Amber1990Zhang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Amber1990Zhang/subscriptions","organizations_url":"https://api.github.com/users/Amber1990Zhang/orgs","repos_url":"https://api.github.com/users/Amber1990Zhang/repos","events_url":"https://api.github.com/users/Amber1990Zhang/events{/privacy}","received_events_url":"https://api.github.com/users/Amber1990Zhang/received_events","type":"User","site_admin":false},"html_url":"https://github.com/Amber1990Zhang/nebula","description":"A high performance distributed Graph Database","fork":true,"url":"https://api.github.com/repos/Amber1990Zhang/nebula","forks_url":"https://api.github.com/repos/Amber1990Zhang/nebula/forks","keys_url":"https://api.github.com/repos/Amber1990Zhang/nebula/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Amber1990Zhang/nebula/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Amber1990Zhang/nebula/teams","hooks_url":"https://api.github.com/repos/Amber1990Zhang/nebula/hooks","issue_events_url":"https://api.github.com/repos/Amber1990Zhang/nebula/issues/events{/number}","events_url":"https://api.github.com/repos/Amber1990Zhang/nebula/events","assignees_url":"https://api.github.com/repos/Amber1990Zhang/nebula/assignees{/user}","branches_url":"https://api.github.com/repos/Amber1990Zhang/nebula/branches{/branch}","tags_url":"https://api.github.com/repos/Amber1990Zhang/nebula/tags","blobs_url":"https://api.github.com/repos/Amber1990Zhang/nebula/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Amber1990Zhang/nebula/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Amber1990Zhang/nebula/git/refs{/sha}","trees_url":"https://api.github.com/repos/Amber1990Zhang/nebula/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Amber1990Zhang/nebula/statuses/{sha}","languages_url":"https://api.github.com/repos/Amber1990Zhang/nebula/languages","stargazers_url":"https://api.github.com/repos/Amber1990Zhang/nebula/stargazers","contributors_url":"https://api.github.com/repos/Amber1990Zhang/nebula/contributors","subscribers_url":"https://api.github.com/repos/Amber1990Zhang/nebula/subscribers","subscription_url":"https://api.github.com/repos/Amber1990Zhang/nebula/subscription","commits_url":"https://api.github.com/repos/Amber1990Zhang/nebula/commits{/sha}","git_commits_url":"https://api.github.com/repos/Amber1990Zhang/nebula/git/commits{/sha}","comments_url":"https://api.github.com/repos/Amber1990Zhang/nebula/comments{/number}","issue_comment_url":"https://api.github.com/repos/Amber1990Zhang/nebula/issues/comments{/number}","contents_url":"https://api.github.com/repos/Amber1990Zhang/nebula/contents/{+path}","compare_url":"https://api.github.com/repos/Amber1990Zhang/nebula/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Amber1990Zhang/nebula/merges","archive_url":"https://api.github.com/repos/Amber1990Zhang/nebula/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Amber1990Zhang/nebula/downloads","issues_url":"https://api.github.com/repos/Amber1990Zhang/nebula/issues{/number}","pulls_url":"https://api.github.com/repos/Amber1990Zhang/nebula/pulls{/number}","milestones_url":"https://api.github.com/repos/Amber1990Zhang/nebula/milestones{/number}","notifications_url":"https://api.github.com/repos/Amber1990Zhang/nebula/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Amber1990Zhang/nebula/labels{/name}","releases_url":"https://api.github.com/repos/Amber1990Zhang/nebula/releases{/id}","deployments_url":"https://api.github.com/repos/Amber1990Zhang/nebula/deployments","created_at":"2019-05-15T07:59:47Z","updated_at":"2019-10-28T03:39:09Z","pushed_at":"2019-10-28T05:32:38Z","git_url":"git://github.com/Amber1990Zhang/nebula.git","ssh_url":"git@github.com:Amber1990Zhang/nebula.git","clone_url":"https://github.com/Amber1990Zhang/nebula.git","svn_url":"https://github.com/Amber1990Zhang/nebula","homepage":"","size":47200,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"vesoft-inc:master","ref":"master","sha":"acaa13ad9f1d0ab73c47bb307124db34f34328af","user":{"login":"vesoft-inc","id":42441426,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQyNDQxNDI2","avatar_url":"https://avatars2.githubusercontent.com/u/42441426?v=4","gravatar_id":"","url":"https://api.github.com/users/vesoft-inc","html_url":"https://github.com/vesoft-inc","followers_url":"https://api.github.com/users/vesoft-inc/followers","following_url":"https://api.github.com/users/vesoft-inc/following{/other_user}","gists_url":"https://api.github.com/users/vesoft-inc/gists{/gist_id}","starred_url":"https://api.github.com/users/vesoft-inc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vesoft-inc/subscriptions","organizations_url":"https://api.github.com/users/vesoft-inc/orgs","repos_url":"https://api.github.com/users/vesoft-inc/repos","events_url":"https://api.github.com/users/vesoft-inc/events{/privacy}","received_events_url":"https://api.github.com/users/vesoft-inc/received_events","type":"Organization","site_admin":false},"repo":{"id":146459443,"node_id":"MDEwOlJlcG9zaXRvcnkxNDY0NTk0NDM=","name":"nebula","full_name":"vesoft-inc/nebula","private":false,"owner":{"login":"vesoft-inc","id":42441426,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQyNDQxNDI2","avatar_url":"https://avatars2.githubusercontent.com/u/42441426?v=4","gravatar_id":"","url":"https://api.github.com/users/vesoft-inc","html_url":"https://github.com/vesoft-inc","followers_url":"https://api.github.com/users/vesoft-inc/followers","following_url":"https://api.github.com/users/vesoft-inc/following{/other_user}","gists_url":"https://api.github.com/users/vesoft-inc/gists{/gist_id}","starred_url":"https://api.github.com/users/vesoft-inc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vesoft-inc/subscriptions","organizations_url":"https://api.github.com/users/vesoft-inc/orgs","repos_url":"https://api.github.com/users/vesoft-inc/repos","events_url":"https://api.github.com/users/vesoft-inc/events{/privacy}","received_events_url":"https://api.github.com/users/vesoft-inc/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/vesoft-inc/nebula","description":"A high performance distributed Graph Database","fork":false,"url":"https://api.github.com/repos/vesoft-inc/nebula","forks_url":"https://api.github.com/repos/vesoft-inc/nebula/forks","keys_url":"https://api.github.com/repos/vesoft-inc/nebula/keys{/key_id}","collaborators_url":"https://api.github.com/repos/vesoft-inc/nebula/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/vesoft-inc/nebula/teams","hooks_url":"https://api.github.com/repos/vesoft-inc/nebula/hooks","issue_events_url":"https://api.github.com/repos/vesoft-inc/nebula/issues/events{/number}","events_url":"https://api.github.com/repos/vesoft-inc/nebula/events","assignees_url":"https://api.github.com/repos/vesoft-inc/nebula/assignees{/user}","branches_url":"https://api.github.com/repos/vesoft-inc/nebula/branches{/branch}","tags_url":"https://api.github.com/repos/vesoft-inc/nebula/tags","blobs_url":"https://api.github.com/repos/vesoft-inc/nebula/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/vesoft-inc/nebula/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/vesoft-inc/nebula/git/refs{/sha}","trees_url":"https://api.github.com/repos/vesoft-inc/nebula/git/trees{/sha}","statuses_url":"https://api.github.com/repos/vesoft-inc/nebula/statuses/{sha}","languages_url":"https://api.github.com/repos/vesoft-inc/nebula/languages","stargazers_url":"https://api.github.com/repos/vesoft-inc/nebula/stargazers","contributors_url":"https://api.github.com/repos/vesoft-inc/nebula/contributors","subscribers_url":"https://api.github.com/repos/vesoft-inc/nebula/subscribers","subscription_url":"https://api.github.com/repos/vesoft-inc/nebula/subscription","commits_url":"https://api.github.com/repos/vesoft-inc/nebula/commits{/sha}","git_commits_url":"https://api.github.com/repos/vesoft-inc/nebula/git/commits{/sha}","comments_url":"https://api.github.com/repos/vesoft-inc/nebula/comments{/number}","issue_comment_url":"https://api.github.com/repos/vesoft-inc/nebula/issues/comments{/number}","contents_url":"https://api.github.com/repos/vesoft-inc/nebula/contents/{+path}","compare_url":"https://api.github.com/repos/vesoft-inc/nebula/compare/{base}...{head}","merges_url":"https://api.github.com/repos/vesoft-inc/nebula/merges","archive_url":"https://api.github.com/repos/vesoft-inc/nebula/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/vesoft-inc/nebula/downloads","issues_url":"https://api.github.com/repos/vesoft-inc/nebula/issues{/number}","pulls_url":"https://api.github.com/repos/vesoft-inc/nebula/pulls{/number}","milestones_url":"https://api.github.com/repos/vesoft-inc/nebula/milestones{/number}","notifications_url":"https://api.github.com/repos/vesoft-inc/nebula/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/vesoft-inc/nebula/labels{/name}","releases_url":"https://api.github.com/repos/vesoft-inc/nebula/releases{/id}","deployments_url":"https://api.github.com/repos/vesoft-inc/nebula/deployments","created_at":"2018-08-28T14:25:09Z","updated_at":"2019-10-28T04:55:39Z","pushed_at":"2019-10-28T05:32:39Z","git_url":"git://github.com/vesoft-inc/nebula.git","ssh_url":"git@github.com:vesoft-inc/nebula.git","clone_url":"https://github.com/vesoft-inc/nebula.git","svn_url":"https://github.com/vesoft-inc/nebula","homepage":"https://nebula-graph.io","size":46694,"stargazers_count":1190,"watchers_count":1190,"language":"C++","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":154,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":187,"license":null,"forks":154,"open_issues":187,"watchers":1190,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138"},"html":{"href":"https://github.com/vesoft-inc/nebula/pull/1138"},"issue":{"href":"https://api.github.com/repos/vesoft-inc/nebula/issues/1138"},"comments":{"href":"https://api.github.com/repos/vesoft-inc/nebula/issues/1138/comments"},"review_comments":{"href":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138/comments"},"review_comment":{"href":"https://api.github.com/repos/vesoft-inc/nebula/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/vesoft-inc/nebula/pulls/1138/commits"},"statuses":{"href":"https://api.github.com/repos/vesoft-inc/nebula/statuses/00dff8eb2d93d1493167347b8dbb836fb990b808"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"whitewum"}}