惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
N
Netflix TechBlog - Medium
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
S
Schneier on Security
T
Threat Research - Cisco Blogs
腾讯CDC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Hacker News
The Hacker News
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
GbyAI
GbyAI
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
T
Tenable Blog
S
Secure Thoughts
T
Threatpost
V2EX - 技术
V2EX - 技术
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
罗磊的独立博客
P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta
小众软件
小众软件
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Y
Y Combinator Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
P
Privacy International News Feed
H
Heimdal Security Blog
量子位
B
Blog

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19) 使用 Velero 备份 Kubernetes 集群 Kubernetes Cheat Sheet 开发 Tips(18) 如何构建一个 Java 工程 开发 Tips(17) KubeSpray 安装 Kubernetes 报错 ip in ansible_all_ipv4_addresses 基于 Kubernetes 和 Jenkins 搭建自动化测试系统 在 Kubernetes 上动态创建 Jenkins Slave 使用 Jenkins 进行服务拨测 开发 Tips(16) Kubernetes 签发 Ingress 证书及日常故障运维 Kubernetes 中 Deployment 的基本操作 Kubernetes 中的证书 如何使用 KubeBuilder 开发一个 Operator Kubernetes 1.6.0 安装问题汇总 镜像管理工具 -- Harbor 开发 Tips(15) Docker 如何拉取镜像 开发 Tips(14) 使用 Helm 安装 harbor 开发 Tips(13) 使用 S2I 构建云原生应用 在 Kubernetes 中使用 emptyDir、hostPath、localVolume 开发 Tips(12) 开发 Tips(11) 代码质量分析工具 SonarQube 使用 Kubeadm 安装 Kubernetes 集群 一起来学 Go --(4)常用函数 Kubernetes 中的 Ceph Kubernetes 之 Volumes Kubernetes 之 Labels、Selectors 开发 Tips(10) 开源正在重构商业模式 Kubernetes 之网络 Kubernetes 之 API 使用 Helm 和 Operator 快速部署 Prometheus Kubernetes 复杂有状态应用管理框架 -- Operator Kubernetes 的包管理器 -- Helm 一起来学 Go --(3)Go Modules 如何一步一步地优化博客方案 kubectl 实用指南 Kubernetes 中的基本概念 搭建远程 Kubernetes 开发环境 大公司和小公司的 ToB 思路 开发 Tips(9) Go 入门指南 一起来学 Go --(2)数据与逻辑结构 如何预防 Web 富文本中的 XSS 攻击 django-xss-cleaner 云工作时代 一起来学 Go --(1)背景与特点 SaaS 开发团队的不同阶段 你不知道的 Git 使用技巧 输出既服务 微服务设计 继续奔跑 开发 Tips(8) 从账户安全到二次验证 Django 性能之数据库查询优化 Django 性能之分库分表 敏捷开发之研发流程 打造一致性的团队 开发 Tips(7) Pytest 进阶学习之 Mock PaaS 部署之 buildpack Go 开发配置 领域输出才是 PaaS 的核心竞争力 Pytest 入门学习 开发 Tips(6) 如何使用 Jenkins、Docker、GitLab 搭建 Django 自动化部署流程
使用 JuiceFS 存储 Elasticsearch 数据
微信公众号 · 2024-05-22 · via 陈少文的网站

Please enable Javascript to view the contents

1. 存储方案

三种存储方案:

  • 基于目录隔离公用一个 JuiceFS

Elasticsearch 的节点共用一个 JuiceFS,通过子目录挂载不同的 Elasticsearch 节点。

/0/ 对应节点 Node-0
/1/ 对应节点 Node-1
/2/ 对应节点 Node-2

这种方式的好处主要是,易于扩展、配置方便。

  • 基于 JuiceFS 隔离节点数据

Elasticsearch 每个节点都对接一个独立的 JuiceFS,每个节点具有单独的存储后端。

Bucket-0 对应节点 Node-0
Bucket-1 对应节点 Node-1
Bucket-2 对应节点 Node-2

这种方式的好处主要是,可靠性高、性能更好。

  • 结合 SSD 冷热数据分离

JuiceFS 的性能不及 SSD,采用混合的方式,将热数据放在 SSD 中,冷数据放在 JuiceFS 中,也是一个不错的选择。

这种方式的好处主要是,兼顾成本与性能,但是运维更加复杂。

目前的业务需求是,使用 Elasticsearch 查询一些温冷数据,但数据体量比较大,达到 10 TB 文本数据,能容忍接口响应时间 10 秒,因此采用的是基于目录隔离的方式。

2. 创建 Elasticsearch 所需的 PVC

2.1. 设置环境变量

  • 设置桶的信息
1
2
3
4
5
6
export ACCESS_KEY=xxx
export SECRET_KEY=xxx
export BUCKET=xxx
export ENDPOINT=ks3-cn-beijing-internal.ksyun.com
export BUCKET_ENPOINT=$BUCKET.$ENDPOINT
export PROVIDER=ks3
  • 设置 Redis
1
2
export REDIS_PASSWORD=xxx
export REDIS_ENDPOINT=x.x.x.x:6379/0
  • 设置 Elasticsearch 的 PVC
1
2
export NAMESPACE=xxx
export PVC_NAME=elasticsearch-data-es-jfs-test-es-default-0

这里需要注意 PVC_NAME 是 ECK Operator 根据 Elasticsearch 的 name 生成的。这里创建的 Elasticsearch 名字为 es-jfs-test,所以 PVC_NAMEelasticsearch-data-es-jfs-test-es-default-0,表示第一个节点的存储卷。

2.2 格式化 JuiceFS

1
2
3
4
5
juicefs format \
    --storage $PROVIDER \
    --bucket $BUCKET_ENPOINT \
    redis://:$REDIS_PASSWORD@$REDIS_ENDPOINT \
    es-jfs-test

2.3 创建 PVC

  • 创建 Dataset
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
kubectl apply -f - <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: $PVC_NAME
  namespace: $NAMESPACE
spec:
  accessModes:
    - ReadWriteMany
  mounts:
    - name: es-jfs-test
      mountPoint: "juicefs://0/"
      options:
        bucket: $BUCKET_ENPOINT
        storage: $PROVIDER
      encryptOptions:
        - name: metaurl
          valueFrom:
            secretKeyRef:
              name: es-jfs-test
              key: metaurl
        - name: access-key
          valueFrom:
            secretKeyRef:
              name: es-jfs-test
              key: access-key
        - name: secret-key
          valueFrom:
            secretKeyRef:
              name: es-jfs-test
              key: secret-key
EOF

需要注意 MountPoint 的格式是 juicefs://0/,表示第一个节点。创建第二个节点时,应该修改为 juicefs://1/

  • 创建 Runtime
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
kubectl apply -f - <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: JuiceFSRuntime
metadata:
  name: $PVC_NAME
  namespace: $NAMESPACE
spec:
  replicas: 1
  juicefsVersion:
    image: juicedata/juicefs-fuse
    imageTag: ce-v1.1.0
  fuse:
    image: juicedata/juicefs-fuse
    imageTag: ce-v1.1.0
    cleanPolicy: OnDemand
  worker:
    resources:
      limits:
        cpu: 15
        memory: 200Gi
  tieredstore:
    levels:
      - mediumtype: SSD
        path: /cache
        quota: 40960   # 40GiB
EOF
  • 创建一个测试的 Pod

创建测试 Pod 不仅仅是为了测试 PVC 能正常挂载,而是提前让 PVC 处理 Bound 状态,避免 Elasticsearch 又重新创建 PVC。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: $PVC_NAME
  namespace: $NAMESPACE
spec:
  containers:
    - name: demo
      image: shaowenchen/demo:ubuntu
      volumeMounts:
        - mountPath: /data/jfs
          name: data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: $PVC_NAME
EOF

参考 在 Kubernetes 下创建后端为 JuiceFS 的 PVC

3. 部署 Elasticsearch

下面是一个简易的部署过程。

3.1 安装 ECK Operator

因为最新版本的 ECK Operator 并不支持 Kubernetes v1.26.9,这里安装的是 ECK Operator v2.11.1。

1
kubectl create -f https://raw.githubusercontent.com/shaowenchen/ops-hub/master/observation/v2.11.1-eck-crds.yaml
1
kubectl apply -f https://raw.githubusercontent.com/shaowenchen/ops-hub/master/observation/v2.11.1-eck-operator.yaml

3.2 部署 Elasticsearch 实例

需要注意的是这里的 count 设置为 1,表示只有一个节点。如果需要使用多个节点,那么需要提前创建对应的 PVC,并且保证其状态为 Bound。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
cat <<EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  namespace: data-center
  name: es-jfs-test
spec:
  version: 8.3.2
  image: elasticsearch:8.3.2
  http:
    tls:
      selfSignedCertificate:
        disabled: true
  nodeSets:
  - name: default
    count: 3
    config:
      node.store.allow_mmap: false
    podTemplate:
      spec:
        initContainers:
        - name: sysctl
          securityContext:
            privileged: true
            runAsUser: 0
          command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
        - name: install-plugins
          command:
            - sh
            - -c
            - |
              bin/elasticsearch-plugin install --batch https://get.infini.cloud/elasticsearch/analysis-ik/8.3.2
          securityContext:
            runAsUser: 0
            runAsGroup: 0
        containers:
        - name: elasticsearch
          env:
            - name: "ES_JAVA_OPTS"
              value: "-Xms30g -Xmx30g"
          resources:
            requests:
              cpu: 10
              memory: 20Gi
            limits:
              cpu: 50
              memory: 500Gi
EOF

3.3 查看 Elasticsearch 密码

1
2
3
kubectl -n $NAMESPACE get secret es-jfs-test-es-elastic-user -o go-template='{{.data.elastic | base64decode}}'

xxx

默认用户名是 elastic

4. 部署 Metricbeat

为了在 Kibana 中能看到 Elasticsearch 的指标数据,需要部署 Metricbeat。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
kubectl apply -f - <<EOF
apiVersion: beat.k8s.elastic.co/v1beta1
kind: Beat
metadata:
  name: es-jfs-test
  namespace: $NAMESPACE
spec:
  type: metricbeat
  version: 8.3.2
  elasticsearchRef:
    name: es-jfs-test
  config:
    metricbeat:
      autodiscover:
        providers:
          - type: kubernetes
            scope: cluster
            hints.enabled: true
            templates:
              - config:
                  - module: kubernetes
                    metricsets:
                      - event
                    period: 10s
    processors:
    - add_cloud_metadata: {}
    logging.json: true
  deployment:
    podTemplate:
      spec:
        serviceAccountName: metricbeat
        automountServiceAccountToken: true
        # required to read /etc/beat.yml
        securityContext:
          runAsUser: 0
EOF
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: metricbeat
rules:
- apiGroups: [""]
  resources:
  - nodes
  - namespaces
  - events
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
  resources:
  - jobs
  verbs: ["get", "list", "watch"]
- apiGroups: ["extensions"]
  resources:
  - replicasets
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources:
  - statefulsets
  - deployments
  - replicasets
  verbs: ["get", "list", "watch"]
- apiGroups:
  - ""
  resources:
  - nodes/stats
  verbs:
  - get
- nonResourceURLs:
  - /metrics
  verbs:
  - get
EOF
1
2
3
4
5
6
7
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metricbeat
  namespace: $NAMESPACE
EOF
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: metricbeat
subjects:
- kind: ServiceAccount
  name: metricbeat
  namespace: $NAMESPACE
roleRef:
  kind: ClusterRole
  name: metricbeat
  apiGroup: rbac.authorization.k8s.io
EOF

5. 部署 Kibana

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
cat <<EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  namespace: $NAMESPACE
  name: es-jfs-test
spec:
  version: 8.3.2
  count: 1
  image: elastic/kibana:8.3.2
  elasticsearchRef:
    name: es-jfs-test
  http:
    tls:
      selfSignedCertificate:
        disabled: true
EOF

编辑 Kibana 的 Service 将 type 改为 NodePort。

1
kubectl -n $NAMESPACE edit svc es-jfs-test-kb-http

此时就可以使用上面的 elastic 用户的密码登录 Kibana 了。

6. 查看 JuiceFS 的文件目录

为了直观的查看一下 Elasticsearch 的文件目录,我在测试主机上挂载了上面的 JuiceFS 用于测试验证。

  • 挂载 JuiceFS 到测试主机
1
2
3
4
5
6
juicefs mount -d \
    --storage $PROVIDER \
    --bucket $BUCKET_ENPOINT \
    redis://:$REDIS_PASSWORD@$REDIS_ENDPOINT \
    es-jfs-test \
    /data/ops/es-jfs-test
  • 查看目录结构
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
tree -L 2
.
├── 0
│   ├── indices
│   ├── mytest
│   ├── node.lock
│   ├── nodes
│   ├── snapshot_cache
│   ├── _state
│   └── test
├── 1
│   ├── indices
│   ├── node.lock
│   ├── nodes
│   ├── snapshot_cache
│   └── _state
└── 2
    ├── indices
    ├── node.lock
    ├── nodes
    ├── snapshot_cache
    └── _state

12 directories, 8 files
  • 查看目录大小

部署完成之后,业务就开始导入数据进行测试了。

7. 总结

AI 相关设备的 CPU、Mem 配置都很高,但大家通常又只关注 GPU、NPU 算力卡的使用率。这导致了 AI 算力设备上 CPU、Mem 的使用率很低。

最近有业务需求,使用 Elasticsearch 分词之后,查询大批量的语料数据,但又对成本非常敏感,不愿意使用 SSD 作为 Elasticsearch 的数据存储。

本篇主要是记录使用 JuiceFS 存储对接 Elasticsearch 的过程,希望能够帮忙大家快速使用上。

8. 参考

https://github.com/elastic/cloud-on-k8s/tree/2.11
https://www.elastic.co/guide/en/cloud-on-k8s/2.11/k8s-quickstart.html


微信公众号