diff --git a/context/jvm-opts.md b/context/jvm-opts.md new file mode 100644 index 0000000000..961207f11f --- /dev/null +++ b/context/jvm-opts.md @@ -0,0 +1,35 @@ +# JVM_OPTS 启动参数 + +Dinky 进程的堆参数通过环境变量 `JVM_OPTS` 注入,`script/bin/auto.sh` 不再写死覆盖。 + +## 解析规则 + +启动脚本在 sourcing `/etc/profile.d/dinky_env`、`/etc/profile.d/dinky_db`、`/etc/profile` 之后执行: + +``` +JVM_OPTS="${JVM_OPTS:-${DEFAULT_JVM_OPTS}}" +``` + +- 已设置且非空:原样使用(整段替换,不是追加)。只想加 GC/诊断参数时,必须把堆参数一并写进 `JVM_OPTS` +- 未设置或为空:回退到脚本默认值 `-Xms512M -Xmx2048M`(空字符串会盖掉镜像 `ENV`,容器里也会落到这组物理机堆参数) +- 启动/重启命令会打印实际生效值 + +不要再设置 `-XX:PermSize` / `-XX:MaxPermSize`:PermGen 在 JDK 8 已移除,HotSpot 会忽略并告警。也不在默认值里加 `-XX:MaxMetaspaceSize`,避免给原先无 Metaspace 上限的进程引入新的 OOM。 + +## 部署默认值 + +| 场景 | 默认 `JVM_OPTS` | 覆盖方式 | +| --- | --- | --- | +| 物理机 / 虚拟机 | `-Xms512M -Xmx2048M` | `export JVM_OPTS=...` 或写入 `/etc/profile.d/dinky_env` | +| Docker 镜像 | `-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0` | `docker run -e JVM_OPTS=...` | +| Helm | 使用镜像默认;未设置则不注入该环境变量 | `spec.extraEnv.jvmOpts` | + +容器场景不要再对 `auto.sh` 做 `sed` 替换。镜像用 `ENV JVM_OPTS` 提供默认值,运行时覆盖即可。 + +## 约束 + +- `deploy/docker/.env` 会同时注入 Dinky 与 Flink JM/TM,不要在该文件里设置 `JVM_OPTS`。 +- docker-compose 的 dinky 服务不要写空的 `environment.JVM_OPTS`:空字符串会覆盖镜像 `ENV`,脚本会回退到物理机堆参数。 +- 使用 `MaxRAMPercentage` 时必须给容器/Pod 设置 memory limit,否则百分比按宿主机可见内存计算,可能过大。 +- 容器默认不设 `InitialRAMPercentage`,避免启动时按 70% 提交堆,把 Metaspace/线程/native 挤出 cgroup。 +- `java ${JVM_OPTS}` 按空格拆分参数,参数值本身不要含未转义空格。 diff --git a/deploy/docker/.env b/deploy/docker/.env index c1086413b5..e5ee9d8a59 100644 --- a/deploy/docker/.env +++ b/deploy/docker/.env @@ -27,6 +27,9 @@ CUSTOM_JAR_PATH=/opt/dinky/extends/ FLINK_PROPERTIES="jobmanager.rpc.address: jobmanager" TZ=Asia/Shanghai +# 不要在此共享 env 中设置 JVM_OPTS(会同时注入 Flink JM/TM)。 +# 仅覆盖 Dinky 时:docker compose run -e JVM_OPTS="-Xms1g -Xmx2g" ... + # mysql,h2,pgsql DB_ACTIVE=h2 diff --git a/deploy/docker/Dockerfile b/deploy/docker/Dockerfile index 45aaa80f27..56a2d55803 100755 --- a/deploy/docker/Dockerfile +++ b/deploy/docker/Dockerfile @@ -14,6 +14,7 @@ RUN cp /opt/flink/opt/flink-python*.jar /opt/flink/lib/ && cp /opt/flink/opt/fli ENV FLINK_VERSION=${FLINK_VERSION} ENV DINKY_HOME=/opt/dinky/ ENV H2_DB=./tmp/db/h2 +ENV JVM_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0" USER root @@ -21,7 +22,7 @@ USER root WORKDIR /opt/dinky/ -RUN mkdir /opt/dinky/customJar && chmod -R 777 /opt/dinky/ && mkdir /dinky && chmod -R 777 /dinky/ && sed -i 's/-Xms512M -Xmx2048M -XX:ermSize=512M/-XX:+UseContainerSupport -XX:InitialRAMPercentage=70.0 -XX:MaxRAMPercentage=70.0/g' ./bin/auto.sh +RUN mkdir /opt/dinky/customJar && chmod -R 777 /opt/dinky/ && mkdir /dinky && chmod -R 777 /dinky/ EXPOSE 8888 diff --git a/deploy/docker/docker-compose.yml b/deploy/docker/docker-compose.yml index f464c4fea3..1bb66de488 100644 --- a/deploy/docker/docker-compose.yml +++ b/deploy/docker/docker-compose.yml @@ -5,6 +5,9 @@ services: image: "dinkydocker/dinky-standalone-server:${DINKY_VERSION}-flink${FLINK_VERSION}" ports: - "8888:8888" + # JVM_OPTS is not listed here on purpose: an empty value would override the + # image default (container RAM percentage). Set it via `docker run -e` or + # add it only to this service when you need a custom heap. env_file: .env networks: - dinky diff --git a/deploy/kubernetes/helm/dinky/templates/dinky.yaml b/deploy/kubernetes/helm/dinky/templates/dinky.yaml index 0d0f2a4401..2b7c08b0be 100755 --- a/deploy/kubernetes/helm/dinky/templates/dinky.yaml +++ b/deploy/kubernetes/helm/dinky/templates/dinky.yaml @@ -73,6 +73,10 @@ spec: {{- end }} {{- end }} {{- include "dinky.dbActive" . | nindent 12 }} + {{- with .Values.spec.extraEnv.jvmOpts }} + - name: JVM_OPTS + value: {{ . | quote }} + {{- end }} envFrom: {{- if .Values.mysql.enabled }} - secretRef: diff --git a/deploy/kubernetes/helm/dinky/values.yaml b/deploy/kubernetes/helm/dinky/values.yaml index a42994c46f..514fbc3f10 100755 --- a/deploy/kubernetes/helm/dinky/values.yaml +++ b/deploy/kubernetes/helm/dinky/values.yaml @@ -69,11 +69,16 @@ spec: name: rest extraEnv: flinkVersion: "1.17" + # Override Dinky JVM options. Leave unset to use the image default + # (UseContainerSupport + 70% of container memory). + # jvmOpts: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0" affinity: {} nodeSelector: {} tolerations: [] resources: {} + # Set memory limits when using the image default MaxRAMPercentage (70%). + # Without a limit, the percentage is taken from node-visible memory. # resources: # limits: # memory: "2Gi" diff --git a/docs/docs/deploy_guide/docker_deploy.md b/docs/docs/deploy_guide/docker_deploy.md index a14deb1c24..3ad5c59445 100644 --- a/docs/docs/deploy_guide/docker_deploy.md +++ b/docs/docs/deploy_guide/docker_deploy.md @@ -49,6 +49,20 @@ docker run --restart=always -p 8888:8888 \ -v /opt/lib:/opt/dinky/customJar/ \ dinkydocker/dinky-standalone-server:1.1.0-flink1.17 ``` + +### 自定义 JVM 内存 + +镜像默认使用容器内存的 70% 作为堆(`UseContainerSupport` + `MaxRAMPercentage`),无需修改启动脚本。通过环境变量 `JVM_OPTS` 覆盖: + +```bash +docker run --restart=always -p 8888:8888 \ + --name dinky \ + -e JVM_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0" \ + dinkydocker/dinky-standalone-server:1.1.0-flink1.17 +``` + +建议同时为容器设置 memory limit(例如 `--memory=2g`),否则百分比会按宿主机可见内存计算。不要在共享的 `deploy/docker/.env` 中设置 `JVM_OPTS`(该文件会同时注入 Flink JM/TM)。不要只把 GC 参数写进 `JVM_OPTS`:该变量是整段替换,不是追加。 + --- ### 使用docker-compose docker-compose可快速帮你搭建起来dinky与flink集群环境, diff --git a/docs/docs/deploy_guide/kubernetes_deploy.md b/docs/docs/deploy_guide/kubernetes_deploy.md index da67d7b0a3..9867465b31 100644 --- a/docs/docs/deploy_guide/kubernetes_deploy.md +++ b/docs/docs/deploy_guide/kubernetes_deploy.md @@ -54,7 +54,11 @@ spec: name: rest extraEnv: flinkVersion: "1.17" + # 可选。不设置则使用镜像默认:容器内存的 70% + # jvmOpts: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0" ``` +自定义 Dinky 进程 JVM 参数时设置 `spec.extraEnv.jvmOpts`,并建议同时配置 `spec.resources.limits.memory`,否则 `MaxRAMPercentage` 会按节点/cgroup 可见内存计算。 + 例如,mysql数据源完整配置如下: 完整配置如下: ```yaml @@ -129,6 +133,8 @@ spec: name: rest extraEnv: flinkVersion: "1.17" + # 可选。不设置则使用镜像默认:容器内存的 70% + # jvmOpts: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0" affinity: {} nodeSelector: {} @@ -285,6 +291,8 @@ spec: name: rest extraEnv: flinkVersion: "1.17" + # 可选。不设置则使用镜像默认:容器内存的 70% + # jvmOpts: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0" affinity: {} nodeSelector: {} diff --git a/docs/docs/deploy_guide/normal_deploy.mdx b/docs/docs/deploy_guide/normal_deploy.mdx index cb46ff43a2..1afa650652 100644 --- a/docs/docs/deploy_guide/normal_deploy.mdx +++ b/docs/docs/deploy_guide/normal_deploy.mdx @@ -239,6 +239,17 @@ sh auto.sh startOnPending 1.20 ``` +#### JVM 内存 + +启动脚本读取环境变量 `JVM_OPTS`,未设置时默认为 `-Xms512M -Xmx2048M`。 + +```shell +export JVM_OPTS="-Xms1g -Xmx4g" +sh ./bin/auto.sh start 1.20 +``` + +也可写入 `/etc/profile.d/dinky_env`。JDK 8 已移除 PermGen,请使用 `-Xms` / `-Xmx`,不要再设置 `-XX:PermSize` / `-XX:MaxPermSize`。 + #### 版本适配 启动指令的第二个参数则是版本选择,支持 【1.14, 1.15, 1.16, 1.17, 1.18, 1.19】,参考指令如下: > 自 1.0.2 版本开始加入了自动检测 Flink 版本的功能,如果不传入版本号,则会自动检测 Flink 版本作为启动版本(即检测 extends 目录下的 flink${FLINK_VERSION} 文件夹) diff --git a/e2e_test/docker-compose-env/Dockerfile b/e2e_test/docker-compose-env/Dockerfile index d4da2358bb..48126f3e80 100644 --- a/e2e_test/docker-compose-env/Dockerfile +++ b/e2e_test/docker-compose-env/Dockerfile @@ -9,6 +9,7 @@ ARG FLINK_VERSION ENV FLINK_VERSION=${FLINK_VERSION} ENV DINKY_HOME=/opt/dinky/ ENV H2_DB=./tmp/db/h2 +ENV JVM_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0" ADD build/dinky-release*.tar.gz /opt RUN ls /opt && mv /opt/dinky-release* /opt/dinky @@ -20,7 +21,7 @@ COPY --from=flink-base /opt/flink/lib/*.jar /opt/dinky/extends/flink${FLINK_VE COPY --from=flink-base /opt/flink/opt/flink-table-planner*.jar /opt/dinky/extends/flink${FLINK_VERSION}/flink/ -RUN mkdir /opt/dinky/customJar && chmod -R 777 /opt/dinky/ && sed -i 's/-Xms512M -Xmx2048M -XX:PermSize=512M/-XX:+UseContainerSupport -XX:InitialRAMPercentage=70.0 -XX:MaxRAMPercentage=70.0/g' ./bin/auto.sh +RUN mkdir /opt/dinky/customJar && chmod -R 777 /opt/dinky/ EXPOSE 8888 diff --git a/script/bin/auto.sh b/script/bin/auto.sh index e565a4a3de..0c0947a4a1 100644 --- a/script/bin/auto.sh +++ b/script/bin/auto.sh @@ -179,8 +179,15 @@ PARAMS_OPT="-Ddinky.logs.path=${DINKY_LOG_PATH} -Ddinky.root.path=${APP_HOME} -D JAR_PARAMS_OPT="--logging.config=${LOG_CONFIG}" # JMX path JMX="-javaagent:$APP_HOME/lib/jmx_prometheus_javaagent-0.20.0.jar=10087:$APP_HOME/config/jmx/jmx_exporter_config.yaml" -#JVM OPTS -JVM_OPTS="-Xms512M -Xmx2048M -XX:PermSize=512M -XX:MaxPermSize=1024M" +# JVM options. Override via JVM_OPTS (Docker ENV / K8s env / systemd / /etc/profile.d/dinky_env). +# PermGen (-XX:PermSize / -XX:MaxPermSize) was removed in JDK 8; do not set them here. +DEFAULT_JVM_OPTS="-Xms512M -Xmx2048M" +JVM_OPTS="${JVM_OPTS:-${DEFAULT_JVM_OPTS}}" +case "$1" in + start|startOnPending|startWithJmx|restart|restartWithJmx) + echo -e "${GREEN}JVM_OPTS : ${JVM_OPTS}${RESET}" + ;; +esac # Check whether the pid path exists PID_PATH="${APP_HOME}/run"