Dgraph部署

作者: 羽_da59 | 来源:发表于2018-11-21 13:12 被阅读1372次

    部署

    本文讨论以分布式的模式运行Dgraph,包括运行多实例的Dgraph,并将多个server构建成一个集群

    1. 安装Dgraph

    github上下载需要的发行版,并解压即可

    2.简单集群构建

    2.1 理解Dgraph集群

    Dgraph是一个真正的分布式图数据库,而不是以master-slave模式复制数据全集的。它根据谓语分片,并在集群中备份谓语,查询可以在任何节点上执行,连接是基于分布式的数据执行的。查询节点自己存储的谓语会在本地执行,而对于存在其他节点上的谓语,会使用分布式的join

    为了更有效地运行Dgraph集群,理解shard、replica以及rebalance时怎么工作的很重要

    2.1.1 Sharding

    Dgraph把每个谓语(在RDF术语中写作* P *)的数据存在一起,因此最小的数据单元时一个谓语。为了把图分片,需要把一个或多个谓语分配到一个group。集群中的每个节点都存有一个group,zero负责把group分配给各个节点

    2.1.2 Shard rebalancing

    Dgraph的zero会试着基于磁盘使用情况进行rebalance。如果Zero检测到数据分布不平衡的情况,它会试着把某个谓语以及它的index、反向边一起转移到磁盘使用最少的group上。这可能会导致这个谓语暂时不可用

    Zero会不断地检查数据分布,每十分钟一次。因此,每个的Dgraph实例都会允许Zero从group中分离某个谓语,并将它转移到一个新的节点上

    2.1.3 一致性Replication

    如果把--replicas标志设置为大于一的整数,Zero会把group分配到多个node上。这些节点将组成一个Raft group,被称作quorum。每个写操作将会被一致地复制到quorum上。为了保证数据一致性,quorum的大小应该时奇数。因此,我们推荐把--replicas设置为1、3或5。这允许0、1或者2个存储同一个group的节点宕机而不影响group的健康

    2.2 直接在host上跑

    2.2.1 运行dgraph zero

    $ dgraph zero --my=IPADDR:7080 --wal zw
    

    默认的Zero端口是7080与8080,7080时Dgraph集群内部不同节点之间数据交互的Grpc端口,而8080是与外部程序数据交互的HTTP端口。你可以使用--port_offset标志改变这些端口

    --my标志是Dgraph与zero联系的拨号盘,因此端口7080以及IP地址必须对其他Dgraph服务器是可见的

    如果想查看所有可用的flag,执行:dgraph zero --help

    2.2.2 运行dgraph server

    dgraph server --idx=2 --memory_mb=<typically half the RAM>
    --my=IPADDR:7081 --zero=localhost:7080 --port_offset=1
    

    Dgraph服务器监听内部端口7080,以及外部HTTP端口8080、外部Grpc端口9080。这些可以通过--port_offset标志指定

    注意--idx标志可以省略,省略的话Zero将会自动地为每个Dgraph server分配一个唯一的ID,Dgraph服务器会将它持久化到wal目录中

    可以使用-p-w修改文件及WAL的存储位置,具体可以执行dgraph server --help

    2.2.3 运行Dgraph UI

    $ dgraph-ratel -p 8081
    

    Dgraph UI默认监听8081端口,可以使用-p标志来修改。默认情况下,ratel会假设dgraph在localhost:8080端口运行,可以在ui中修改这个地址

    注意 ratel需要访问Amazon下载css与js

    2.3 高可用性配置

    在高可用性配置中,我们需要运行三个或五个Zero,以及三个或五个server

    注意

    如果replica的数量是2K+1,至多K个server宕机的情况下,读写可以不受任何影响

    避免把replica设置为2K(偶数),这样如果K个服务器宕机,将会导致阻塞读写

    2.3.1 Dgraph Zero

    运行三个实例,并通过--idx给每一个分配一个唯一ID,并通过--peer发送一个健康的Zero实例的地址(会自动加入集群?像redis那样?)

    为了让server实例保存三个复制,设置--replicas=3。每当添加一个新的Dgraph服务器,Zero将会检查已有的group,并给它们分配一个复制数不是三的group

    依次启动三个zero:

    ./dgraph zero --idx 100  --port_offset 100 --my 10.181.105.100:7180 --wal ../data/zw --replicas 3
    ./dgraph zero --idx 101  --port_offset 100 --my 10.181.105.101:7180 --peer 10.181.105.100:7180 --wal ../data/zw --replicas 3
    ./dgraph zero --idx 102  --port_offset 100 --my 10.181.105.102:7180 --peer 10.181.105.101:7180 --wal ../data/zw --replicas 3
    

    2.3.2 Dgraph Server

    Run as many Dgraph servers as you want。可以手动设置--idx标志,如果不设的话也可以,Zero 会给server自动分配一个id。这个id将会被保存在wal中,所以不要删除wal

    新的server会联系zero自动检测其他的server,并互相建立连接。通常,Zero首先会通过分配一个server运行已有的group来尝试复制一个group。如果所有的分组都已经安装 —replicas标志复制好了,Zero会创建一个新的分组。随着时间的发展,数据会被均匀地被分割到不同的group中。因此,需要确保Dgraph server的数量是replication设置的整数倍。

    例如,如果在Zero中设置--replicas=3,那么运行三个server的话,不会有sharding,但是有3x的复制。如果运行六个serer,那么会把数据shard到两个group中,仍然有3x复制

    依次启动三个server:

    ./dgraph server --idx 200 --port_offset 200 --memory_mb 51200 --my 10.181.105.100:7280 --zero 10.181.105.102:7180 --postings ../data/p --wal ../data/w
    ./dgraph server --idx 201 --port_offset 200 --memory_mb 51200 --my 10.181.105.101:7280 --zero 10.181.105.100:7180 --postings ../data/p --wal ../data/w
    ./dgraph server --idx 202 --port_offset 200 --memory_mb 51200 --my 10.181.105.102:7280 --zero 10.181.105.101:7180 --postings ../data/p --wal ../data/w
    

    2.3.4 移除死节点

    如果一个人复制坏掉,并且不能被恢复,可以移除它并向quorum中添加一个新节点。Zero中的/removeNode可以用于移除死节点(/removeNode?id=3&group=2)

    注意

    在使用API之前,必须先确定节点宕了,并确保它不会再恢复了

    在添加新复制的时候,记得设置idx标志,否则Zero会给它设置一个新的分组

    3. 从源码构建

    确保安装了Go (version >= 1.8)

    之后,执行:

    # This should install dgraph binary in your $GOPATH/bin.
    $ go get -u -v github.com/dgraph-io/dgraph/dgraph
    

    如果在build的时候,报了grpc的错,你的go-grpc版本可能太老了。我们不提供go-groc(因为在使用Go client的时候它会有问题)。通过运行如下命令更新go-grpc

    $ go get -u -v google.golang.org/grpc
    

    4. More about Dgraph

    在http端口上,一个运行中的Dgraph实例有一系列的管理终端:

    • / Browser UI and query visualization.
    • /health HTTP status code 200 and “OK” message if worker is running, HTTP 503 otherwise.
    • /admin/shutdown shutdown a node.
    • /admin/export take a running export.

    默认情况下,server会监听localhost(只有本机可见的本地环网地址),可以使用 --bindall=true 选项绑定到 0.0.0.0 ,监听外部链接

    注意 如果你准备load大量数据,把最大文件描述符设置为像10000这样的大值

    5. More about Dgraph Zero

    Dgraph Zero控制Dgraph集群。它会基于每个实例存储数据的大小自动地在集群中移动数据

    在运行任何dgraph server之前,必须至少有一个dgraph zero

    • Zero存储集群的信息
    • --replicas是控制复制因子的选项(例如每个数据分片的复制数,包括原始分片)
    • 每当一个新的机器启动,zero会基于复制因子给它分配一个group。如果复制因子是1,那么每个节点都会保存不同的group。如果复制因子是2,摒弃启动了4个节点,那么前面两个节点会保存group1,后面两个保存group2
    • Zero也会监控每个group的谓语占用的空间大小,并会通过移动它们来平衡集群

    像Dgrph一样,Zero也有使用HTTP端口8080(+port_offset)。可以通过查询它来获取有用的信息,如下:

    • /state 集群中节点的信息,包括谓语的size,以及它们所属的组
    • /removeNode?id=idx&group=gid 用于从quorum中移除死掉的节点,节点id与groupid是所需的参数

    查看state信息:

    {
      "counter": "26",
      "groups": {
        "1": {
          "members": {
            "200": {
              "id": "200",
              "groupId": 1,
              "addr": "10.181.105.100:7280",
              "leader": true,
              "lastUpdate": "1515398876"
            },
            "201": {
              "id": "201",
              "groupId": 1,
              "addr": "10.181.105.101:7280"
            },
            "202": {
              "id": "202",
              "groupId": 1,
              "addr": "10.181.105.102:7280"
            }
          },
          "tablets": {
            "_dummy_": {
              "groupId": 1,
              "predicate": "_dummy_",
              "space": "19"
            }
          }
        }
      },
      "zeros": {
        "100": {
          "id": "100",
          "addr": "10.181.105.100:7180",
          "leader": true
        },
        "101": {
          "id": "101",
          "addr": "10.181.105.101:7180"
        },
        "102": {
          "id": "102",
          "addr": "10.181.105.102:7180"
        }
      }
    }
    

    6. 配置

    可以用--help参数查看zero与server的所有配置项

    可以通过多种方式进行配置(按优先级从高到低):

    • 使用命令行标志
    • 使用环境变量
    • 使用配置文件

    多种配置方式可以同时使用,例如配置文件用于保存核心信息,命令行标志用于为每个实例制定参数

    环境变量本人不推荐使用,不翻译了

    配置文件支持的格式包括JSON、TOML、YAML、HCL以及Java properties,通过文件扩展名识别

    配置文件可以通过--config标签或者环境变量指定,例如:

    $ dgraph zero --config my_config.json
    

    配置文件的结构就是简单的键值对,例如JSON格式配置文件如下:

    {
      "idx": 42,
      "peer": 192.168.0.55:9080,
      "replicas": 2
    }
    

    7. TSL配置

    client到server之间的连接可以通过TLS提高安全,支持加密(密码保护)与非加密私钥

    如果你使用openssl生成加密私钥,必须明确指定加密算法(例如-aes256)。这回强制openssl在私钥中包含DEK-Info头,这需要Dgraph解密key。如果使用默认加密方式,openssl不会写头,因此key无法被解密

    server有如下参数可以配置:

    # Use TLS connections with clients.
    tls_on
    
    # CA Certs file path.
    tls_ca_certs string
    
    # Include System CA into CA Certs.
    tls_use_system_ca
    
    # Certificate file path.
    tls_cert string
    
    # Certificate key file path.
    tls_cert_key string
    
    # Certificate key passphrase.
    tls_cert_key_passphrase string
    
    # Enable TLS client authentication
    tls_client_auth string
    
    # TLS max version. (default "TLS12")
    tls_max_version string
    
    # TLS min version. (default "TLS11")
    tls_min_version string
    

    Dgraph loader可以通过如下参数设置:

    # Use TLS connections.
    tls_on
    
    # CA Certs file path.
    tls_ca_certs string
    
    # Include System CA into CA Certs.
    tls_use_system_ca
    
    # Certificate file path.
    tls_cert string
    
    # Certificate key file path.
    tls_cert_key string
    
    # Certificate key passphrase.
    tls_cert_key_passphrase string
    
    # Server name.
    tls_server_name string
    
    # Skip certificate validation (insecure)
    tls_insecure
    
    # TLS max version. (default "TLS12")
    tls_max_version string
    
    # TLS min version. (default "TLS11")
    tls_min_version string
    

    8. 集群Checklist

    在创建集群的时候,确保检查了如下项:

    • 是不是至少一个dgraph zero节点在运行
    • 是否集群中的每个实例都被正确配置
    • 是不是每个实例都能通过7080 (+ any port offset)访问所有peer
    • 是不是每个节点在启动的时候都有一个唯一ID
    • 是不是设置了 --bindall=true

    9. 快速数据导入

    有两个工具可以进行数据批量导入:

    • dgraph live
    • dgraph bulk

    注意

    这两个工具都只能接受gzip压缩的RDF NQuad/Triple数据。其他格式的数据必须先转换

    9.1 Live Loader

    dgraph live是一个从gzip压缩文件中读取RDF Nquads,把它们分批,使用go client创建mutation,并导入Dgraph的工具

    Live loader可以正确地给多个文件中的空节点分配唯一ID,并将它们持久化到磁盘,以节省内存并应付loader重新执行的情况

    $ dgraph live --help # To see the available flags.
    
    # Read RDFs from the passed file, and send them to Dgraph on localhost:9080.
    $ dgraph live -r <path-to-rdf-gzipped-file>
    
    # Read RDFs and a schema file and send to Dgraph running at given address
    $ dgraph live -r <path-to-rdf-gzipped-file> -s <path-to-schema-file> -d <dgraph-server-address:port>
    

    9.2 Bulk Loader

    注意

    调整bulk loader的参数以提高性能非常重要

    Bulk loader的功能与live loader很像,但是只能被用于dgraph离线,并准备初始化的情况。它不能运行在一个已有的dgraph实例

    警告

    千万不要在Dgraph服务启动的时候执行bulk loader。用它把已有的数据导入一个新的Dgraph实例

    Bulk loader比live loader快相当多,但是它只被推荐用于大数据集初始化导入dgraph

    可以参看read some technical details博客来了解技术细节

    你需要决定集群中希望的dgraph实例的数量,并将reduce shard的数量设置为这个数。你还需要把map shard的数量至少设置为跟这个数相等(数量越大,bulk loader就会把谓语在reduce shard中分布的梗平均)

    下面的例子,使用了2个reduce shard以及4个map shard:

    dgraph-bulk-loader -r=goldendata.rdf.gz -s=goldendata.schema --map_shards=4 --reduce_shards=2
    {
            "RDFDir": "goldendata.rdf.gz",
            "SchemaFile": "goldendata.schema",
            "DgraphsDir": "out",
            "LeaseFile": "LEASE",
            "TmpDir": "tmp",
            "NumGoroutines": 4,
            "MapBufSize": 67108864,
            "ExpandEdges": true,
            "BlockRate": 0,
            "SkipMapPhase": false,
            "CleanupTmp": true,
            "NumShufflers": 1,
            "Version": false,
            "MapShards": 4,
            "ReduceShards": 2
    }
    MAP 01s rdf_count:219.0k rdf_speed:218.7k/sec edge_count:693.4k edge_speed:692.7k/sec
    MAP 02s rdf_count:494.2k rdf_speed:247.0k/sec edge_count:1.596M edge_speed:797.7k/sec
    MAP 03s rdf_count:749.4k rdf_speed:249.4k/sec edge_count:2.459M edge_speed:818.3k/sec
    MAP 04s rdf_count:1.005M rdf_speed:250.8k/sec edge_count:3.308M edge_speed:826.1k/sec
    MAP 05s rdf_count:1.121M rdf_speed:223.9k/sec edge_count:3.695M edge_speed:738.3k/sec
    MAP 06s rdf_count:1.121M rdf_speed:186.6k/sec edge_count:3.695M edge_speed:615.3k/sec
    MAP 07s rdf_count:1.121M rdf_speed:160.0k/sec edge_count:3.695M edge_speed:527.5k/sec
    REDUCE 08s [22.68%] edge_count:837.9k edge_speed:837.9k/sec plist_count:450.2k plist_speed:450.2k/sec
    REDUCE 09s [40.79%] edge_count:1.507M edge_speed:1.507M/sec plist_count:905.8k plist_speed:905.7k/sec
    REDUCE 10s [79.91%] edge_count:2.953M edge_speed:1.476M/sec plist_count:1.395M plist_speed:697.3k/sec
    REDUCE 11s [100.00%] edge_count:3.695M edge_speed:1.231M/sec plist_count:1.778M plist_speed:592.5k/sec
    REDUCE 11s [100.00%] edge_count:3.695M edge_speed:1.182M/sec plist_count:1.778M plist_speed:568.8k/sec
    Total: 11s
    

    数据生成之后,你可以在启动server的时候使用-p参数指定输出的目录。如果运行了多个Dgraph server,你需要把输出的shard拷贝到不同的服务器上

    cd out/i # i = shard number.
    dgraph server -zero=localhost:7080 -memory_mb=1024
    

    9.2.1 性能调优

    Tip

    我们强烈推荐在执行Bulk Loader的时候禁用swap空间。修复参数减少内存使用,比swap导致loader宕机好

    可以使用标志来控制bulk loader的行为及性能特点。可以使用dgraph bulk --help查看所有的参数。特别要注意,需要调整参数使bulk loader不会使用超过RAM大小的内存。一旦开始swap,它将变的特别慢

    Map

    在map语句中,修改下面的参数可以降低内存使用:

    • --num_go_routines 标志控制worker线程的数量,数值越小,占用的内存越少
    • --mapoutput_mb 标志控制map输出文件的大小,数值越小,占用的内存越少

    对于更大的数据集,以及有很多core的服务器,map中的gzip解码可能会成为瓶颈,可以首先把RDF拆分成多个.rdf.gz文件(例如每个256MB)。这对内存使用会有略微的影响

    Reduce

    Reduce语句对内存的压力比map小,尽管它仍然可能会使用很多内存。有些参数可以提高性能,但是只有在你有很大的RAM的情况下使用:

    • --reduce_shards 控制产生的dgraph实例数。增大
    • The --map_shards flag controls the number of separate map output shards. Increasing this increases memory consumption but balances the resultant dgraph instances more evenly.
    • The --shufflers controls the level of parallelism in the shuffle/reduce stage. Increasing this increases memory consumption.

    10. 导出

    可以访问集群中任意节点的终端,导出所有节点的数据:

    $ curl localhost:8080/admin/export
    

    Warning 如果从dgraph运行的服务器之外调用是无效的

    Dgraph也提供了一个HTTP GET接口,可以在Dgraph运行的服务器上调用

    这个接口可以导出集群中所有的group的数据。每个服务器都会把输出写入到gzip压缩的rdf文件,文件路径可以通过--export参数指定。如果某个group失败了,所有的export进程都会失败,并返回错误

    Note 用户需要自己到集群中的服务器上拿导出的数据文件,Dgraph不会把文件拷到执行导出的服务器

    11. 关机

    可以通过执行如下命令,将一个Dgraph节点的安全退出:

    curl localhost:8080/admin/shutdown
    

    Warning 如果从运行的dgraph之外的服务器执行是无效的

    这会停止执行命令的服务器上的Dgraph,而不是停止整个Dgraph集群

    12. 删除数据库

    如果要删除所有的数据,可以使用Alter 终端的DropAll请求

    或者,你也可以:

    • 关闭Dgraph,并等待所有写入完成
    • 删除pw目录,然后
    • 重启Dgraph

    13. 升级Dgraph

    周期性的数据导出是个好主意。特别是当你希望升级数据库,或者重新配置集群的分片时。下面是数据安全导出与重启的正确步骤:

    • 开启一个导出任务
    • 确保导出成功
    • 关闭集群
    • 使用新数据目录运行Dgraph
    • 通过bulk loader重新导入数据
    • 如果都成功了,你可以删除旧目录(数据导出是为了保证数据安全)

    14. 监控

    Dgraph通过/debug/vars终端以json格式返回监控指标。Dgraph不存储监控指标,只是返回当时的值。你可以将数据存储在监控系统,或者安装Prometheus

    将下面配置文件中的ip配置为你的dgraph实例,并用如下命令运行prometheus:

    $ prometheus -config.file my_config.yaml
    
    scrape_configs:
      - job_name: "dgraph"
        metrics_path: "/debug/prometheus_metrics"
        scrape_interval: "2s"
        static_configs:
        - targets:
          - 172.31.9.133:8080
          - 172.31.15.230:8080
          - 172.31.0.170:8080
          - 172.31.8.118:8080
    

    安装Grafana用于绘制监控指标。Grafana默认会在3000端口上运行。用如下步骤创建一个prometheus数据源。通过如下链接导入一个grafana_dashboard.json

    15. Troubleshooting

    下面是一些常见的问题及解决办法

    15.1 OOM(out of memory)

    在bulk loading数据的时候,Dgraph可能会消耗更多的内存,因为会有大量写入。因此你可能会遇到OOM问题

    推荐的最小RAM是16GB。当使用默认的—memory_mb=4096设置时,Dgraph可能会占用7-8GB

    在EC2/GCE实例上,我们推荐最小RAM是8GB。推荐将-memory_mb设置为RAM的一半

    相关文章

      网友评论

        本文标题:Dgraph部署

        本文链接:https://www.haomeiwen.com/subject/aykofftx.html