V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
429463267
V2EX  ›  程序员

请教个问题:存储海量数据的多个 ES 集群之间,如何实现负载均衡,网关分流

  •  1
     
  •   429463267 · 8 天前 · 967 次点击

    现有一个生产集群,由于数据量太大,遇到性能瓶颈,而且未来数据量还会继续扩大,打算将数据分集群拆开,尽量保证已部署的几十个 spark 服务不做修改或少量修改。

    其中,spark 读写 ES 采用的是 ES 9200 端口,写多读少,ip 是写死的内网 ip,已上生产。

    所以,目前的想法是,将现有的 ES 集群拆分为多个,假定为 5 ( ES-cluster1 、ES-cluster2 、ES-cluster3 、ES-cluster4 、ES-cluster5 ) 个新集群。

    那么,拆完以后,不同的 index pattern 会落到不同集群上,拆分过程可能会很繁琐,估计会使用迁移工具完成。

    于是需要一个 API gatway 之类的服务来分发 spark 发来的 http 请求,使得相应的请求映射到正确的新集群上。

    接着,我调研了市面上可用的方案如下:

    1.https://opster.com/configuration/multi-cluster-load-balancer-configuration/
    为 ES 量身定制的负载均衡工具,闭源产品,而且文档基本没有,沟通全靠邮件,放弃。

    2.Kong https://github.com/kong/kong

    3.https://github.com/traefik/traefik

    2 3 之间同类产品对比如下:
    微服务五种开源 API 网关实现组件对比 - 知乎
    https://zhuanlan.zhihu.com/p/61014955

    8 款开源的 Kubernetes Ingress Controller/API Gateway 推荐 · Service Mesh|服务网格中文社区
    https://www.servicemesher.com/blog/nginx-ingress-vs-kong-vs-traefik-vs-haproxy-vs-voyager-vs-contour-vs-ambassador/

    ingress 控制器那么多,到底该选哪一个?累觉不爱。 - 知乎
    https://zhuanlan.zhihu.com/p/302452502


    初步结论,暂定选择 kong 或者 traefix 来实现,但还在纠结选哪个。

    请各位大佬指点迷津。

    20 条回复    2021-07-26 10:45:55 +08:00
    429463267
        1
    429463267   8 天前
    misaka19000
        2
    misaka19000   8 天前
    Kong 好像挺好的
    429463267
        3
    429463267   8 天前 via Android
    既然 es JAVA 客户端使用 http 协议通信,那么在网关层,可以通过请求的 method 、host 、path 、query params 、reqbody 来动态映射目标 es 集群
    plko345
        4
    plko345   8 天前 via Android
    在 k8s 集群中?
    429463267
        5
    429463267   8 天前
    @plko345 没在 k8s,在 AWS 服务器上
    beyondsoft
        6
    beyondsoft   8 天前
    投 Kong 一票
    defunct9
        7
    defunct9   8 天前
    traefik,空重了
    tanxnative
        8
    tanxnative   8 天前
    自己写一下吧,写和读用一样的分片算法就好了
    429463267
        9
    429463267   8 天前
    @tanxnative 如果只有一个集群的话,可以通过分片算法来分发数据,
    但是多个集群之间,目前没有现成方案。
    429463267
        10
    429463267   8 天前
    @defunct9 https://sm.ms/image/Msbm1uINDnLAl5d

    traefik 看上去略显弱势
    defunct9
        13
    defunct9   8 天前
    @429463267 traefik 和 nginx ingress 都在使用,由于之前 nginx 用太多了,最近都在搞 traefik,感觉 traefik 很好用
    plko345
        14
    plko345   8 天前 via Android
    对 es 只了解一点,“不同的 index pattern 会落到不同集群上“是不是就是根据 url 的 path 和参数进行 7 层的转发,如果是的话,nginx,haproxy,traefik 全都支持,选个熟悉的?性能 nginx 和 haproxy 差不多,traefik 好像弱一点
    429463267
        15
    429463267   8 天前
    @plko345

    这是我用 fiddler 抓到的包,详细记录了 spark 使用 ESHaghilevelClient 写入数据的 HTTP 报文:

    ```http

    ### spark ESOperator 写入
    POST http://1.2.3.4:9200/_bulk?timeout=1m HTTP/1.1
    Content-Length: 500
    Content-Type: application/json
    Host: 1.2.3.4:9200
    Connection: Keep-Alive
    User-Agent: Apache-HttpAsyncClient/4.1.4 (Java/1.8.0_181)
    Authorization: Basic ***

    {"index":{"_index":"index2","_id":"3"}}
    {"content":"这是内容 3","doc_id":3,"headline":"标题 3"}
    {"index":{"_index":"index2","_id":"4"}}
    {"content":"这是内容 4","doc_id":4,"headline":"标题 4"}
    {"index":{"_index":"index1","_id":"1"}}
    {"content":"这是内容 1","doc_id":1,"headline":"标题 1"}
    {"index":{"_index":"index1","_id":"2"}}
    {"content":"这是内容 2","doc_id":2,"headline":"标题 2"}
    {"index":{"_index":"index1","_id":"1"}}
    {"content":"这是内容 5","doc_id":1,"headline":"标题 5"}

    ### 响应
    HTTP/1.1 200 OK
    content-type: application/json; charset=UTF-8
    content-length: 928

    {"took":1731,"errors":false,"items":[{"index":{"_index":"index2","_type":"_doc","_id":"3","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1,"status":201}},{"index":{"_index":"index2","_type":"_doc","_id":"4","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":1,"_primary_term":1,"status":201}},{"index":{"_index":"index1","_type":"_doc","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1,"status":201}},{"index":{"_index":"index1","_type":"_doc","_id":"2","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":1,"_primary_term":1,"status":201}},{"index":{"_index":"index1","_type":"_doc","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":2,"_primary_term":1,"status":200}}]}
    ###

    ### ESClient 删除 index
    DELETE http://12.3.4:9200/index1 HTTP/1.1
    Content-Length: 0
    Host: 1.2.3.4:9200
    Connection: Keep-Alive
    User-Agent: Apache-HttpAsyncClient/4.1.4 (Java/1.8.0_181)
    Authorization: Basic ***

    ### 响应
    HTTP/1.1 200 OK
    content-type: application/json; charset=UTF-8
    content-length: 21

    {"acknowledged":true}
    ###
    ```

    初步想法是解析 ReqBody,然后根据 index 名称拆分为多个 http 请求发到对应的 ES 集群上,最后响应全部结果给客户端。
    但是响应的报文格式应该是无法兼容 ESHighLevelClient 。。。
    429463267
        16
    429463267   8 天前
    https://www.cnblogs.com/zhoujie/p/kong2.html

    看了 kong 的文档,发现他的 路由能力太弱了,无法解析请求体。
    Morriaty
        17
    Morriaty   7 天前
    有个中国 elastic 员工写的 https://github.com/medcl/infini-gateway,a high performance and lightweight gateway written in golang, for elasticsearch and his friends.

    唯一的问题是,emm,It is currently under heavy developemnt, API or configurations are not supposed to be stable.
    429463267
        18
    429463267   7 天前
    @Morriaty 谢谢老哥,我去围观下
    429463267
        19
    429463267   7 天前
    @Morriaty
    下载源码看了一眼,有很多依赖都是来自一个 infini.sh 的站点,然鹅,这个站点已经无法访问了。所以二次开发受阻。
    Morriaty
        20
    Morriaty   4 天前
    @429463267 作者 issue 里有提,这个网站在维护
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2041 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:06 · PVG 23:06 · LAX 08:06 · JFK 11:06
    ♥ Do have faith in what you're doing.