diff --git a/helm/name-lookup/Chart.yaml b/helm/name-lookup/Chart.yaml index bd5ada548..94b7a8849 100644 --- a/helm/name-lookup/Chart.yaml +++ b/helm/name-lookup/Chart.yaml @@ -14,11 +14,11 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 0.5.2 +version: 0.6.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -# +# # NameRes versions are based on the version of the NameRes Docker image concatenated with the # Babel release date. -appVersion: 1.5.2_2025sep1 +appVersion: 1.7.0_2026jul22 diff --git a/helm/name-lookup/ncats-images-meta.yaml b/helm/name-lookup/ncats-images-meta.yaml index e89fde446..552714dbe 100644 --- a/helm/name-lookup/ncats-images-meta.yaml +++ b/helm/name-lookup/ncats-images-meta.yaml @@ -1,10 +1,10 @@ nameLookup: image: ghcr.io/ncatstranslator/nameresolution - version: v1.5.2 + version: v1.7.0 solr: image: solr - version: "9.1" + version: "9.10" renciPythonImage: image: ghcr.io/translatorsri/renci-python-image diff --git a/helm/name-lookup/renci-dev-values-populated.yaml b/helm/name-lookup/renci-dev-values-populated.yaml index 9686e14d0..6b1c8fc9b 100644 Binary files a/helm/name-lookup/renci-dev-values-populated.yaml and b/helm/name-lookup/renci-dev-values-populated.yaml differ diff --git a/helm/name-lookup/renci-exp-values-populated.yaml b/helm/name-lookup/renci-exp-values-populated.yaml index 40beda9fe..8ede4fb30 100644 Binary files a/helm/name-lookup/renci-exp-values-populated.yaml and b/helm/name-lookup/renci-exp-values-populated.yaml differ diff --git a/helm/name-lookup/templates/restore-job.yaml b/helm/name-lookup/templates/restore-job.yaml index 1f7eb30d3..4135f8d7f 100644 --- a/helm/name-lookup/templates/restore-job.yaml +++ b/helm/name-lookup/templates/restore-job.yaml @@ -23,10 +23,8 @@ spec: requests: storage: {{ .Values.blocklist.storage }} {{ end }} - # Because of the way in which the Restore Job works -- by creating fields in - # the Solr database, including copy fields -- it can no longer be re-run on - # failure. Instead, it should fail so we can look at the error output and - # figure out what to do next. + # The restore job now only deletes blocklisted CURIEs (the schema and data + # come baked into the backup), so it is idempotent and safe to re-run. restartPolicy: Never containers: - name: restore-container diff --git a/helm/name-lookup/templates/scripts-config-map.yaml b/helm/name-lookup/templates/scripts-config-map.yaml index 189c73720..92cf4df24 100644 --- a/helm/name-lookup/templates/scripts-config-map.yaml +++ b/helm/name-lookup/templates/scripts-config-map.yaml @@ -9,21 +9,52 @@ data: #!/bin/bash set -xa DATA_DIR="/var/solr/data" - BACKUP_NAME="snapshot.backup" - BACKUP_ZIP="${BACKUP_NAME}.tar.gz" + CORE_DIR="${DATA_DIR}/name_lookup" + BACKUP_ZIP="${DATA_DIR}/snapshot.backup.tar.gz" BACKUP_URL="{{ .Values.dataUrl }}" + STAMP="${CORE_DIR}/.dataUrl" - rm -rf $DATA_DIR/* + # An empty dataUrl means "leave the volume alone" -- keep whatever core is already + # there (or none). This is the switch for "do not (re)load", same as before. + if [ -z "${BACKUP_URL}" ]; then + echo "dataUrl is empty; leaving any existing core untouched." + exit 0 + fi + + # The backup is a self-contained Solr core (config + schema + index). Skip the + # download only if the extracted core came from THIS dataUrl: a pod restart with an + # unchanged dataUrl keeps the good core (translator-devops#609), but a new release + # (changed dataUrl) reloads instead of silently serving the old index on a PVC that + # outlived the version bump. A core with no stamp (old logic, or hand-restored) + # reloads once so the served data matches the configured dataUrl. + if [ -f "${CORE_DIR}/core.properties" ] && [ "$(cat "${STAMP}" 2>/dev/null)" = "${BACKUP_URL}" ]; then + echo "Core already present from ${BACKUP_URL}; skipping download." + exit 0 + fi + + # Otherwise start clean and download. + rm -rf ${DATA_DIR}/* # Download the file with retries if the download fails or if there is an existing file we can continue. - wget -c --progress=dot:giga --tries=10 --waitretry=10 --timeout=60 --read-timeout=30 -O $DATA_DIR/$BACKUP_ZIP $BACKUP_URL + wget -c --progress=dot:giga --tries=10 --waitretry=10 --timeout=60 --read-timeout=30 -O ${BACKUP_ZIP} ${BACKUP_URL} - cd $DATA_DIR - tar -xf $DATA_DIR/$BACKUP_ZIP -C $DATA_DIR - rm $DATA_DIR/$BACKUP_ZIP + # Extract the core into the Solr home. Solr auto-discovers name_lookup on startup, + # with its schema and config baked in -- nothing else to set up. + tar -xf ${BACKUP_ZIP} -C ${DATA_DIR} + rm ${BACKUP_ZIP} + + # Record which backup this core came from, so the next pod start can tell a restart + # (skip) from a version bump (reload). Written after a successful extract so a + # failed download never leaves a stamp that would suppress the retry. + printf '%s' "${BACKUP_URL}" > "${STAMP}" restore.sh: |- #!/bin/sh + # + # The backup already contains the loaded index AND the schema/config, so there + # is no collection to create, no replication restore, and no fields to add. The + # only post-restore work is deleting blocklisted CURIEs, if a blocklist is set. + # (This makes the job idempotent and safe to re-run -- see NameResolution#185.) BLOCKLIST_DIR="/var/blocklist" BLOCKLIST_CHUNK_SIZE=500 @@ -46,169 +77,19 @@ data: COLLECTION_NAME="name_lookup" SOLR_SERVER=http://{{ include "name-lookup.fullname" . }}-solr-svc:{{ .Values.solr.service.port }} - # liveliness check - - HEALTH_ENDPOINT=http://{{ include "name-lookup.fullname" . }}-solr-svc:{{ .Values.solr.service.port }}/solr/admin/cores?action=STATUS + # Wait for Solr and the auto-discovered core to be ready. + HEALTH_ENDPOINT=${SOLR_SERVER}/solr/${COLLECTION_NAME}/admin/ping response=$(wget --spider --server-response ${HEALTH_ENDPOINT} 2>&1 | grep "HTTP/" | awk '{ print $2 }') >&2 until [ "$response" = "200" ]; do response=$(wget --spider --server-response ${HEALTH_ENDPOINT} 2>&1 | grep "HTTP/" | awk '{ print $2 }') >&2 - echo " -- SOLR is unavailable - sleeping" + echo " -- SOLR is unavailable - sleeping" sleep 3 done - - # solr is ready Now we create collection if it doesn't exist - - EXISTS=$(wget -O - ${SOLR_SERVER}/solr/admin/collections?action=LIST | grep name_lookup) - - # create collection / shard - if [ -z "$EXISTS" ] - then - wget -O- ${SOLR_SERVER}/solr/admin/collections?action=CREATE'&'name=${COLLECTION_NAME}'&'numShards=1'&'replicationFactor=1 - sleep 3 - fi - - # Setup fields for search - wget --post-data '{"set-user-property": {"update.autoCreateFields": "false"}}' \ - --header='Content-Type:application/json' \ - -O- ${SOLR_SERVER}/solr/${COLLECTION_NAME}/config - sleep 1 - - # Restore data - BACKUP_NAME="backup" - CORE_NAME=${COLLECTION_NAME}_shard1_replica_n1 - RESTORE_URL=${SOLR_SERVER}/solr/${CORE_NAME}/replication?command=restore'&'location=/var/solr/data/var/solr/data/'&'name=${BACKUP_NAME} - wget -O - $RESTORE_URL - sleep 10 - RESTORE_STATUS=$(wget -q -O - ${SOLR_SERVER}/solr/${CORE_NAME}/replication?command=restorestatus 2>&1 | grep "success") >&2 - echo "Restore status: " $RESTORE_STATUS - until [ ! -z $RESTORE_STATUS ] ; do - echo "restore not done , probably still loading. Note: if this takes too long please check solr health" - RESTORE_STATUS=$(wget -O - ${SOLR_SERVER}/solr/${CORE_NAME}/replication?command=restorestatus 2>&1 | grep "success") >&2 - sleep 10 - done - echo "restore done" - wget --post-data '{ - "add-field-type" : { - "name": "LowerTextField", - "class": "solr.TextField", - "positionIncrementGap": "100", - "analyzer": { - "tokenizer": { - "class": "solr.StandardTokenizerFactory" - }, - "filters": [{ - "class": "solr.LowerCaseFilterFactory" - }] - } - }}' \ - --header='Content-Type:application/json' \ - -O- ${SOLR_SERVER}/solr/${COLLECTION_NAME}/schema - sleep 1 - # exactish type taken from https://stackoverflow.com/a/29105025/27310 - wget --post-data '{ - "add-field-type" : { - "name": "exactish", - "class": "solr.TextField", - "analyzer": { - "tokenizer": { - "class": "solr.KeywordTokenizerFactory" - }, - "filters": [{ - "class": "solr.LowerCaseFilterFactory" - }] - } - }}' \ - --header='Content-Type:application/json' \ - -O- ${SOLR_SERVER}/solr/${COLLECTION_NAME}/schema - sleep 1 - wget --post-data '{ - "add-field": [ - { - "name":"names", - "type":"LowerTextField", - "stored": true, - "multiValued": true - }, - { - "name":"names_exactish", - "type":"exactish", - "indexed":true, - "stored":true, - "multiValued":true - }, - { - "name":"curie", - "type":"string", - "stored":true - }, - { - "name": "preferred_name", - "type": "LowerTextField", - "stored": true - }, - { - "name": "preferred_name_exactish", - "type": "exactish", - "indexed": true, - "stored": false, - "multiValued": false - }, - { - "name": "types", - "type": "string", - "stored": true, - "multiValued": true - }, - { - "name": "shortest_name_length", - "type": "pint", - "stored": true - }, - { - "name": "curie_suffix", - "type": "plong", - "docValues": true, - "stored": true, - "required": false, - "sortMissingLast": true - }, - { - "name": "taxa", - "type": "string", - "stored": true, - "multiValued": true - }, - { - "name": "clique_identifier_count", - "type": "pint", - "stored": true - } - ] - }' \ - --header='Content-Type:application/json' \ - -O- ${SOLR_SERVER}/solr/${COLLECTION_NAME}/schema - sleep 1 - wget --post-data '{ - "add-copy-field" : { - "source": "names", - "dest": "names_exactish" - }}' \ - --header='Content-Type:application/json' \ - -O- ${SOLR_SERVER}/solr/${COLLECTION_NAME}/schema - wget --post-data '{ - "add-copy-field" : { - "source": "preferred_name", - "dest": "preferred_name_exactish" - }}' \ - --header='Content-Type:application/json' \ - -O- ${SOLR_SERVER}/solr/${COLLECTION_NAME}/schema - sleep 1 + echo "Solr core ${COLLECTION_NAME} is up." # Delete the blocklist terms from the Solr database. {{ if .Values.blocklist.url }} - BLOCKLIST_DIR=/var/blocklist - # Split the blocklist into files of 500 CURIEs each. rm -rf ${BLOCKLIST_DIR}/blocklist_* split -l ${BLOCKLIST_CHUNK_SIZE} ${BLOCKLIST_DIR}/blocklist.txt ${BLOCKLIST_DIR}/blocklist_ diff --git a/helm/name-lookup/templates/secrets.yaml b/helm/name-lookup/templates/secrets.yaml index dd34667e0..43f145a1c 100644 --- a/helm/name-lookup/templates/secrets.yaml +++ b/helm/name-lookup/templates/secrets.yaml @@ -1,3 +1,12 @@ +{{- /* + Fail fast rather than quietly deploying a blocklist that cannot authenticate: if the + blocklist is switched on (blocklist.url set) there must be a token to go with it. The + token is looked up nil-safely here so that a values file which drops the `secrets` map + entirely still gets this message instead of a raw nil-pointer error. +*/ -}} +{{- if and .Values.blocklist.url (not (.Values.blocklist.secrets).github_personal_access_token) }} +{{- fail "blocklist.url is set but blocklist.secrets.github_personal_access_token is empty. Set the token, or clear blocklist.url to turn the blocklist off. (If the blocklist URL needs no auth, set any non-empty placeholder.)" }} +{{- end }} {{ if .Values.blocklist.secrets.github_personal_access_token }} apiVersion: v1 kind: Secret diff --git a/helm/name-lookup/templates/solr-deployment.yaml b/helm/name-lookup/templates/solr-deployment.yaml index b7cccbd8d..50c532d6f 100644 --- a/helm/name-lookup/templates/solr-deployment.yaml +++ b/helm/name-lookup/templates/solr-deployment.yaml @@ -44,9 +44,10 @@ spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.solr.image.repository }}:{{ .Values.solr.image.tag }}" + # Standalone mode: no -DzkRun/ZooKeeper. The backup is a self-contained + # core that the download init-container extracts into /var/solr/data, so + # Solr auto-discovers name_lookup on startup with its schema baked in. args: - - '-DzkRun' - - '-DzkClientTimeout=5000' - '-q' - '-Dlog4j2.disable.jmx=true' - '-Dlog4j2.formatMsgNoLookups=true' @@ -57,6 +58,11 @@ spec: value: {{ include "name-lookup.fullname" . }}-solr-svc - name: GC_TUNE value: {{ .Values.solr.gc | quote }} + {{- if .Values.solr.gc_log }} + # Overrides Solr's default file-based GC logging (see solr.gc_log in values.yaml). + - name: GC_LOG_OPTS + value: {{ .Values.solr.gc_log | quote }} + {{- end }} # "-XX:-UseLargePages -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=30 -XX:G1NewSizePercent=5 -XX:G1HeapRegionSize=32M -XX:InitiatingHeapOccupancyPercent=70" # "-XX:-UseLargePages -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=20 -XX:G1NewSizePercent=5 -XX:G1HeapRegionSize=32M -XX:InitiatingHeapOccupancyPercent=20" # "-XX:+UseG1GC -XX:MaxGCPauseMillis=1000 -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=40 -XX:G1NewSizePercent=5 -XX:G1HeapRegionSize=32M -XX:InitiatingHeapOccupancyPercent=90" diff --git a/helm/name-lookup/templates/web-deployment.yaml b/helm/name-lookup/templates/web-deployment.yaml index d0d2ebc12..d9631c1dd 100644 --- a/helm/name-lookup/templates/web-deployment.yaml +++ b/helm/name-lookup/templates/web-deployment.yaml @@ -40,11 +40,17 @@ spec: value: "{{ .Values.app.otel.jaegerHost }}" - name: "JAEGER_PORT" value: "{{ .Values.app.otel.jaegerPort }}" + # Logging level. + - name: LOGLEVEL + value: "{{ .Values.app.logLevel }}" # Babel version information. - name: BABEL_VERSION value: "{{ .Values.data.babelVersion }}" - name: BABEL_VERSION_URL value: "{{ .Values.data.babelVersionURL }}" + # Biolink Model tag. + - name: BIOLINK_MODEL_TAG + value: "{{ .Values.data.biolinkModelTag }}" ports: - name: http containerPort: {{ .Values.webServer.port }} diff --git a/helm/name-lookup/values.yaml b/helm/name-lookup/values.yaml index 50fd18d4e..1621f73b4 100644 --- a/helm/name-lookup/values.yaml +++ b/helm/name-lookup/values.yaml @@ -13,13 +13,14 @@ webServer: port: 2433 image: repository: ghcr.io/ncatstranslator/nameresolution - tag: v1.5.2 + tag: v1.7.0 -dataUrl: "https://stars.renci.org/var/babel_outputs/2025sep1/nameres/snapshot.backup.tar.gz" +dataUrl: "https://stars.renci.org/var/babel_outputs/2026jul22/nameres/snapshot.backup.tar.gz" forceRun: false data: - babelVersion: 2025sep1 - babelVersionURL: https://github.com/ncatstranslator/Babel/blob/master/releases/2025sep1.md + babelVersion: 2026jul22 + babelVersionURL: https://github.com/ncatstranslator/Babel/blob/master/releases/2026jul22.md + biolinkModelTag: "v4.4.3" downloader: image: @@ -39,29 +40,58 @@ solr: port: 8983 image: repository: solr - tag: 9.1 + # Solr load happens using Solr 9.10.0 version, but any Solr 9.10.x should be able to + # load that database. This allows our frontline database to pick up minor updates. + # Quoted: unquoted YAML 9.10 parses as the float 9.1, which pulled solr:9.1 and + # failed core init against a 9.10-built index (NameResolution#278). + tag: "9.10" + # The memory limit is the single biggest serving-performance lever. It has to + # cover the JVM heap (heap_mem below, 16G) AND leave the rest for the OS page + # cache, which is charged to the cgroup limit and is what actually keeps queries + # fast: Lucene reads the index through page cache, so the more of the ~111Gi index + # (Babel 2026jul22) that fits in (limit - heap), the fewer reads fall through to + # the network (`basic`) disk. A past measurement on a large limit showed ~11-13Gi + # of JVM RSS against ~111Gi of page cache -- Solr wants close to the whole index + # cached. + # + # 64Gi gives ~48Gi of page cache (~43% of the index) -- a big step up from 32Gi's + # ~16Gi (~15%), and enough for reasonable performance. If queries are slow and the + # Grafana page-cache panel shows the cache pinned at (limit - heap) -- or /status + # reports an index `size` well above (limit - heap), so most of it cannot be + # cached -- raise the limit further. 128Gi caches essentially the whole index; the + # Dev instance (most used) is the one to raise first. + # + # When you change the memory limit: + # - Keep requests == limits. Page cache needs guaranteed (not burstable) memory, + # and the node has to actually have it -- check `kubectl describe node`. + # - Do NOT raise heap_mem to match. The extra memory should go to page cache, not + # the heap. NameRes issues no fq and caches whole query results in + # queryResultCache (bounded by maxRamMB in the configset), so 16G of heap is + # plenty, and a heap over ~32G also gives up compressed object pointers. See + # NameResolution#265. + # - cpu and storage do not scale with the memory limit. + # ephemeral-storage covers everything the pod writes outside the PVC: Solr's log files + # in /var/solr/logs (which is NOT on the PVC -- only /var/solr/data is mounted) plus the + # container's stdout, which the kubelet also writes to node disk and bills here. + # + # The bounded part is about 640Mi: solr.log and solr_slow_requests.log each roll at + # 32MB x 10. (Clearing solr.gc_log above adds a further ~180Mi of solr_gc.log.) The + # variable part is Jetty's NCSA request log, one file per day kept for 3 days + # (solr.log.requestlog.retaindays), so it grows with query volume -- that is what the + # headroom below is for. To shrink it, pass -Dsolr.log.requestlog.retaindays=1. + # + # Note this limit EVICTS the pod when exceeded, so it is deliberately generous: an + # undersized value would turn a rare node-disk-pressure eviction into a routine one + # under heavy traffic. Raise the limit rather than trimming it if request logs grow. resources: - # We tried increasing this to 200Gi. It looks like Solr used the following - # amounts of memory (as per Sterling Grafana): - # - Memory Usage (WSS): 13Gi - # - Memory Usage (RSS): 11Gi - # - Memory Usage (Cache): 111Gi - # - # I think the "cache" here refers to the OS-level page cache, which makes - # sense, as the Solr indexes occupy around 127Gi. - # - # Therefore, I suspect that Solr needs about 32-64Gi to load its indexes - # and other important content, but will use other memory if it is available - # to cache content. We'll set this to 64Gi for now, but we should try - # bombarding these instances with queries to check how valuable increasing - # the memory to Solr helps with performance. - # requests: - memory: "32Gi" + memory: "64Gi" cpu: 4000m + ephemeral-storage: 2Gi limits: - memory: "32Gi" + memory: "64Gi" cpu: 6000m + ephemeral-storage: 8Gi # You can control the nodeSelector/affinity/tolerations settings for Solr with the following settings. # Other pods (web, restore, backup) are controlled via app.nodeSelector/affinity/tolerations below. @@ -69,12 +99,34 @@ solr: affinity: tolerations: - heap_mem: "-Xms30G -Xmx30G" + # Keep the JVM heap well below the pod's memory limit so the rest stays available + # for the OS page cache, which is what actually keeps the ~127Gi index fast (Lucene + # relies on it). See NameResolution#265 -- raising the memory limit above and tuning + # the exact heap is tracked there and should be validated under query load. + heap_mem: "-Xms16G -Xmx16G" gc: "-XX:NewSize=4G -XX:MaxNewSize=4G -XX:+UseG1GC -XX:MaxGCPauseMillis=1000 -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=40 -XX:G1NewSizePercent=5 -XX:G1HeapRegionSize=32M -XX:InitiatingHeapOccupancyPercent=90" - # As of Babel 2023jul13, we need 130G to store the - # uncompressed backup + 131G Solr database - # So 300Gi should be enough for the time being. + # Send GC logs to stdout so the cluster log collector (Grafana) picks them up. + # + # Solr's default is -Xlog:gc*:file=$SOLR_LOGS_DIR/solr_gc.log:...:filecount=9,filesize=20M, + # which writes to /var/solr/logs -- a directory that is NOT on the PVC (only + # /var/solr/data is mounted), so the GC log is ephemeral and vanishes on the pod + # restart that usually prompts you to go looking for it. Routing to stdout makes it + # durable in Grafana and drops ~180Mi of ephemeral log files. + # + # Note this is `-Xlog:gc`, not `-Xlog:gc*`: the bare form logs one line per collection + # (the pause summary), which is what you need to correlate against a latency tail. The + # `gc*` form adds every GC subcomponent and is very chatty on a 16G heap. Use `gc*` + # temporarily if you are debugging GC itself. + # + # Set to "" to fall back to Solr's default file-based GC logging. + gc_log: "-Xlog:gc:stdout:time,uptime" + + # Holds the extracted Solr index. download.sh streams the compressed backup in, + # untars it, and deletes the tarball, so peak usage is roughly the index (~111Gi for + # Babel 2026jul22) plus the compressed tarball during the download (tens of Gi) -- + # there is no longer an uncompressed-backup staging copy (NameResolution#278). 400Gi + # leaves generous headroom, and does not need to scale with solr.resources. storage: 400Gi # As far as I know, initresources are only used by the download @@ -97,16 +149,23 @@ app: enabled: false jaegerHost: jaegerPort: + logLevel: INFO nodeSelector: affinity: tolerations: + # The web pod writes no data files, so its ephemeral-storage is almost entirely stdout + # that the kubelet spools to node disk: NameRes logs one INFO line per lookup, which is + # a lot of lines at production query rates. The kubelet rotates container logs, so this + # only needs enough headroom to sit above that rotation comfortably. resources: requests: memory: 1Gi cpu: 750m + ephemeral-storage: 512Mi limits: memory: 2Gi cpu: 1000m + ephemeral-storage: 2Gi nameOverride: "" fullnameOverride: "" @@ -127,6 +186,17 @@ blocklist: # in `blocklist.secrets.github_personal_access_token` in an encrypted file. You can also # set this on Kubernetes by running: # kubectl -n $NAMESPACE create secret generic {{name-lookup.fullname}}-secrets --from-literal=github_personal_access_token=github_pat_... + # + # Declared here (rather than left unset) so the key always exists: templates reference it + # directly, and an undefined `secrets` map made rendering die with an unhelpful + # "nil pointer evaluating interface {}.github_personal_access_token" even when the + # blocklist was deliberately turned off. + # + # Rendering fails fast if blocklist.url is set while this is empty -- turning the + # blocklist on without a token is almost always a mistake. If the blocklist URL is + # genuinely public and needs no auth, set any non-empty placeholder here. + secrets: + github_personal_access_token: "" # The storage necessary to store the blocklist file. This is currently an ephemeral volume, and because we need # to use `split` to split this into 500 ID chunks, we actually need TWICE the amount of storage needed to store # the blocklist. Luckily, the blocklist is about 7KB right now, so 100Mi should be future proof for a while. diff --git a/helm/node-normalization-loader/Chart.yaml b/helm/node-normalization-loader/Chart.yaml index 2c7bcafdd..32660561b 100644 --- a/helm/node-normalization-loader/Chart.yaml +++ b/helm/node-normalization-loader/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.7.0 +version: 0.8.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -23,4 +23,4 @@ version: 0.7.0 # # NodeNorm versions are based on the version of the NodeNorm Docker image concatenated with the # Babel release date. -appVersion: 2.3.26_2025sep1 +appVersion: 2.5.1_2026jul22 diff --git a/helm/node-normalization-loader/ncats-dev-values.yaml b/helm/node-normalization-loader/ncats-dev-values.yaml index facad89ea..f3ad2d948 100644 Binary files a/helm/node-normalization-loader/ncats-dev-values.yaml and b/helm/node-normalization-loader/ncats-dev-values.yaml differ diff --git a/helm/node-normalization-loader/ncats-images-meta.yaml b/helm/node-normalization-loader/ncats-images-meta.yaml index 3fe75f91a..021d7dae3 100644 --- a/helm/node-normalization-loader/ncats-images-meta.yaml +++ b/helm/node-normalization-loader/ncats-images-meta.yaml @@ -1,3 +1,3 @@ nodeNormalizationLoader: image: "ghcr.io/ncatstranslator/nodenormalization-data-loading" - version: "v2.3.26" + version: "v2.5.1" diff --git a/helm/node-normalization-loader/ncats-prod-values.yaml b/helm/node-normalization-loader/ncats-prod-values.yaml index b7f2873df..f941c6de5 100644 Binary files a/helm/node-normalization-loader/ncats-prod-values.yaml and b/helm/node-normalization-loader/ncats-prod-values.yaml differ diff --git a/helm/node-normalization-loader/ncats-test-values.yaml b/helm/node-normalization-loader/ncats-test-values.yaml index 41ae0fe16..2d9ea6c03 100644 Binary files a/helm/node-normalization-loader/ncats-test-values.yaml and b/helm/node-normalization-loader/ncats-test-values.yaml differ diff --git a/helm/node-normalization-loader/renci-dev-values-populated.yaml b/helm/node-normalization-loader/renci-dev-values-populated.yaml index 5c5e26536..4da1cba68 100644 Binary files a/helm/node-normalization-loader/renci-dev-values-populated.yaml and b/helm/node-normalization-loader/renci-dev-values-populated.yaml differ diff --git a/helm/node-normalization-loader/renci-exp-values-populated.yaml b/helm/node-normalization-loader/renci-exp-values-populated.yaml index ffd631e1d..1ec13bf78 100644 Binary files a/helm/node-normalization-loader/renci-exp-values-populated.yaml and b/helm/node-normalization-loader/renci-exp-values-populated.yaml differ diff --git a/helm/node-normalization-loader/templates/loader-config.yaml b/helm/node-normalization-loader/templates/loader-config.yaml index b45ec2a67..5f5caf847 100644 --- a/helm/node-normalization-loader/templates/loader-config.yaml +++ b/helm/node-normalization-loader/templates/loader-config.yaml @@ -12,6 +12,7 @@ data: "data_files": ["{{$compendia}}"], "test_mode": 0, "debug_messages": 1, + "biolink_version": "{{ $.Values.biolink_version }}", "conflations" : [] } {{ end }} @@ -40,6 +41,7 @@ data: "data_files": [], "test_mode": 0, "debug_messages": 1, + "biolink_version": "{{ $.Values.biolink_version }}", "conflations" : [ { "types" : {{ $conflation.types | toJson }}, diff --git a/helm/node-normalization-loader/templates/loader-pipe-job.yaml b/helm/node-normalization-loader/templates/loader-pipe-job.yaml index 14454fa75..d1e53f568 100644 --- a/helm/node-normalization-loader/templates/loader-pipe-job.yaml +++ b/helm/node-normalization-loader/templates/loader-pipe-job.yaml @@ -8,6 +8,7 @@ {{- $tag := .Values.restore.tag }} {{- $pullPolicy := .Values.restore.pullPolicy }} {{- $ephemeralStorage := .Values.restore.ephemeralStorage }} +{{- $redisConfig := .Values.redis_config }} {{- range $dbName, $dbConf := .Values.redis_backend_config }} {{- $dbKubeName := $dbName | replace "_" "-"}} {{- $dataStorageSize := $dbConf.storageSize }} @@ -18,6 +19,7 @@ {{- $sslEnabled := $connectionDetails.ssl_enabled }} {{- $isCluster := $connectionDetails.is_cluster }} {{- $redisPassword := $connectionDetails.password }} +{{- $redisVersion := $connectionDetails.redis_version | default $redisConfig.redis_version | default "6.2" }} apiVersion: batch/v1 kind: Job metadata: @@ -103,6 +105,7 @@ data: gunzip "{{ $dataDir }}/{{ $dbName }}.rdb.gz" # Restore the file into the specified database. + # We no longer need to support cluster mode, so we can just pipe the data directly to the target host. # The `-c` option doesn't work in pipe mode, which is why we generate a ton of MOVED errors when we run this. The `grep -v MOVED` should suppress them # to avoid filling up the log. # Instead, what we will do is to get the list of cluster nodes and then stream ALL the data to ALL the nodes. Very inefficient, but it should get the job done. @@ -115,14 +118,34 @@ data: for node in $sub_nodes; do IFS=':' read -ra node_host_port <<< $node sub_host_name="${node_host_port[0]}" - echo "... Started piping data to ${sub_host_name} as part of {{ $hostName }} ..." - rdb -c protocol "{{ $dataDir }}/{{ $dbName }}.rdb" | redis-cli {{ if $isCluster }}-c{{end}} -h ${sub_host_name} -p {{ $port }} --pipe {{ if $sslEnabled -}}--tls{{ end }} 2>&1 | grep -v MOVED + echo "... Started piping data to ${sub_host_name} as part of {{ $hostName }} ..." + bash /home/nru/rdb-to-resp.sh "{{ $dataDir }}/{{ $dbName }}.rdb" "{{$redisVersion}}" | redis-cli {{ if $isCluster }}-c{{end}} -h ${sub_host_name} -p {{ $port }} --pipe {{ if $sslEnabled -}}--tls{{ end }} 2>&1 | grep -v MOVED + # rdb -c protocol "{{ $dataDir }}/{{ $dbName }}.rdb" | redis-cli {{ if $isCluster }}-c{{end}} -h ${sub_host_name} -p {{ $port }} --pipe {{ if $sslEnabled -}}--tls{{ end }} 2>&1 | grep -v MOVED echo "... Done piping data to ${sub_host_name} as part of {{ $hostName }} ..." done {{ if not $isCluster }} - # Start a BGSAVE so the database is backed up to disk and ready to be loaded from if necessary. - redis-cli -h {{ $hostName }} -p {{ $port }} {{ if $sslEnabled -}}--tls{{ end }} {{ if $isCluster }}-c{{end}} BGSAVE + # Persist the restored data to disk before this Job exits, so that if the pod + # restarts it reloads a complete dump.rdb instead of coming up empty. A plain + # BGSAVE is fire-and-forget, so we trigger it and then wait for it to actually + # finish and verify it succeeded. The dataset is static once the pipe above + # completes, so the fork is cheap. + REDIS="redis-cli -h {{ $hostName }} -p {{ $port }} {{ if $sslEnabled -}}--tls{{ end }}" + $REDIS CONFIG SET save "" + PREV_SAVE=$($REDIS LASTSAVE) + $REDIS BGSAVE + echo "Waiting for BGSAVE to complete on {{ $hostName }}..." + for i in $(seq 1 900); do + if [ "$($REDIS LASTSAVE)" -gt "$PREV_SAVE" ] 2>/dev/null; then break; fi + if [ "$($REDIS INFO persistence | tr -d '\r' | sed -n 's/^rdb_last_bgsave_status://p')" = "err" ]; then + echo "ERROR: BGSAVE failed on {{ $hostName }}." >&2; exit 1 + fi + sleep 2 + done + if [ "$($REDIS LASTSAVE)" -le "$PREV_SAVE" ] 2>/dev/null; then + echo "ERROR: BGSAVE did not complete within the timeout on {{ $hostName }}." >&2; exit 1 + fi + echo "Restored data persisted to dump.rdb on {{ $hostName }}." {{- end }} # Report success. diff --git a/helm/node-normalization-loader/values.yaml b/helm/node-normalization-loader/values.yaml index 85aa495ef..b2514c542 100644 --- a/helm/node-normalization-loader/values.yaml +++ b/helm/node-normalization-loader/values.yaml @@ -10,16 +10,20 @@ mode: restore # Log level for loading jobs. logLevel: INFO +# Biolink Model version (any ref from https://github.com/biolink/biolink-model is fine, but this should match the +# version used by the loaded Babel run) +biolink_version: "v4.4.3" + image: repository: "ghcr.io/ncatstranslator/nodenormalization" - tag: "v2.3.26" + tag: "v2.5.1" pullPolicy: Always fullnameOverride: "" # Settings to use for a restore job. restore: repository: "ghcr.io/ncatstranslator/nodenormalization-data-loading" - tag: "v2.3.26" + tag: "v2.5.1" pullPolicy: Always dataDir: "/data" dataSize: 50G @@ -33,7 +37,7 @@ app: data: compendia: storageSize: 10G - sourceBaseUrl: "https://stars.renci.org/var/babel_outputs/2025sep1/compendia/" + sourceBaseUrl: "https://stars.renci.org/var/babel_outputs/2026jul22/compendia/" files: - AnatomicalEntity.txt - BiologicalProcess.txt @@ -45,7 +49,7 @@ data: - ComplexMolecularMixture.txt - Disease.txt - Drug.txt - - GeneFamily.txt + - Food.txt - Gene.txt.00 - Gene.txt.01 - Gene.txt.02 @@ -53,6 +57,8 @@ data: - Gene.txt.04 - Gene.txt.05 - Gene.txt.06 + - Gene.txt.07 + - GeneFamily.txt - GrossAnatomicalStructure.txt - MacromolecularComplex.txt - MolecularActivity.txt @@ -77,20 +83,11 @@ data: - Protein.txt.13 - Protein.txt.14 - Protein.txt.15 - - Protein.txt.16 - - Protein.txt.17 - - Protein.txt.18 - - Protein.txt.19 - - Protein.txt.20 - - Protein.txt.21 - - Protein.txt.22 - - Protein.txt.23 - - Protein.txt.24 - - Protein.txt.25 - Publication.txt.00 - Publication.txt.01 - Publication.txt.02 - Publication.txt.03 + - Publication.txt.04 - SmallMolecule.txt.00 - SmallMolecule.txt.01 - SmallMolecule.txt.02 @@ -106,7 +103,7 @@ data: - umls.txt conflations: storageSize: 1G - sourceBaseUrl: "https://stars.renci.org/var/babel_outputs/2025sep1/conflation/" + sourceBaseUrl: "https://stars.renci.org/var/babel_outputs/2026jul22/conflation/" configs: - file: "GeneProtein.txt" types: @@ -120,33 +117,36 @@ data: redis_db: "chemical_drug_db" codeDir: /code +redis_config: + redis_version: "6.2" + redis_backend_config: "eq_id_to_id_db": - restoreURL: "https://stars.renci.org/var/babel_outputs/2025sep1/rdb-backups/id-id.rdb.gz" + restoreURL: "https://stars.renci.org/var/babel_outputs/2026jul22/rdb-backups/id-id.rdb.gz" storageSize: 100G "id_to_eqids_db": - restoreURL: "https://stars.renci.org/var/babel_outputs/2025sep1/rdb-backups/id-eq-id.rdb.gz" + restoreURL: "https://stars.renci.org/var/babel_outputs/2026jul22/rdb-backups/id-eq-id.rdb.gz" storageSize: 150G "id_to_type_db": - restoreURL: "https://stars.renci.org/var/babel_outputs/2025sep1/rdb-backups/id-categories.rdb.gz" + restoreURL: "https://stars.renci.org/var/babel_outputs/2026jul22/rdb-backups/id-categories.rdb.gz" storageSize: 30G "curie_to_bl_type_db": - restoreURL: "https://stars.renci.org/var/babel_outputs/2025sep1/rdb-backups/semantic-count.rdb.gz" + restoreURL: "https://stars.renci.org/var/babel_outputs/2026jul22/rdb-backups/semantic-count.rdb.gz" storageSize: 1G "gene_protein_db": - restoreURL: "https://stars.renci.org/var/babel_outputs/2025sep1/rdb-backups/conflation-db.rdb.gz" + restoreURL: "https://stars.renci.org/var/babel_outputs/2026jul22/rdb-backups/conflation-db.rdb.gz" storageSize: 10G "info_content_db": - restoreURL: "https://stars.renci.org/var/babel_outputs/2025sep1/rdb-backups/info-content.rdb.gz" + restoreURL: "https://stars.renci.org/var/babel_outputs/2026jul22/rdb-backups/info-content.rdb.gz" storageSize: 1G "chemical_drug_db": - restoreURL: "https://stars.renci.org/var/babel_outputs/2025sep1/rdb-backups/chemical-drug-db.rdb.gz" + restoreURL: "https://stars.renci.org/var/babel_outputs/2026jul22/rdb-backups/chemical-drug-db.rdb.gz" storageSize: 1G securityContext: diff --git a/helm/node-normalization-web-server/Chart.yaml b/helm/node-normalization-web-server/Chart.yaml index 8fe677722..d76a376f6 100644 --- a/helm/node-normalization-web-server/Chart.yaml +++ b/helm/node-normalization-web-server/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.4.2 +version: 0.4.3 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -23,4 +23,4 @@ version: 0.4.2 # # NodeNorm versions are based on the version of the NodeNorm Docker image concatenated with the # Babel release date. -appVersion: 2.4.1_2025sep1 +appVersion: 2.5.1_2026jul22 diff --git a/helm/node-normalization-web-server/ncats-images-meta.yaml b/helm/node-normalization-web-server/ncats-images-meta.yaml index c167d0926..6edf709c4 100644 --- a/helm/node-normalization-web-server/ncats-images-meta.yaml +++ b/helm/node-normalization-web-server/ncats-images-meta.yaml @@ -1,4 +1,4 @@ nodeNormalization: image: ghcr.io/ncatstranslator/nodenormalization - version: v2.4.1 + version: v2.5.1 diff --git a/helm/node-normalization-web-server/renci-dev-values-populated.yaml b/helm/node-normalization-web-server/renci-dev-values-populated.yaml index 3956d9d2f..5f9d67360 100644 Binary files a/helm/node-normalization-web-server/renci-dev-values-populated.yaml and b/helm/node-normalization-web-server/renci-dev-values-populated.yaml differ diff --git a/helm/node-normalization-web-server/renci-exp-values-populated.yaml b/helm/node-normalization-web-server/renci-exp-values-populated.yaml index 137edfa55..3cbd65ee2 100644 Binary files a/helm/node-normalization-web-server/renci-exp-values-populated.yaml and b/helm/node-normalization-web-server/renci-exp-values-populated.yaml differ diff --git a/helm/node-normalization-web-server/values.yaml b/helm/node-normalization-web-server/values.yaml index 8d67ca772..87b7bca37 100644 --- a/helm/node-normalization-web-server/values.yaml +++ b/helm/node-normalization-web-server/values.yaml @@ -8,13 +8,13 @@ image: repository: ghcr.io/ncatstranslator/nodenormalization - tag: v2.4.1 + tag: v2.5.1 pullPolicy: Always data: - babelVersion: "2025sep1" - babelVersionURL: "https://github.com/ncatstranslator/Babel/blob/master/releases/2025sep1.md" - biolinkModelTag: "v4.2.6-rc5" + babelVersion: "2026jul22" + babelVersionURL: "https://github.com/ncatstranslator/Babel/blob/master/releases/2026jul22.md" + biolinkModelTag: "v4.4.3" web: port: 8080 diff --git a/helm/redis-r3-external/Chart.lock b/helm/redis-r3-external/Chart.lock index 0443915f1..9f4a704fc 100644 --- a/helm/redis-r3-external/Chart.lock +++ b/helm/redis-r3-external/Chart.lock @@ -1,24 +1,24 @@ dependencies: - name: redis repository: https://charts.bitnami.com/bitnami - version: 23.1.1 + version: 27.0.15 - name: redis repository: https://charts.bitnami.com/bitnami - version: 23.1.1 + version: 27.0.15 - name: redis repository: https://charts.bitnami.com/bitnami - version: 23.1.1 + version: 27.0.15 - name: redis repository: https://charts.bitnami.com/bitnami - version: 23.1.1 + version: 27.0.15 - name: redis repository: https://charts.bitnami.com/bitnami - version: 23.1.1 + version: 27.0.15 - name: redis repository: https://charts.bitnami.com/bitnami - version: 23.1.1 + version: 27.0.15 - name: redis repository: https://charts.bitnami.com/bitnami - version: 23.1.1 -digest: sha256:a3d9a85dbd1e011438ead44845622f6dc576dec48ccde4aeb7f64e66e2bae03c -generated: "2025-10-08T22:44:56.5247-04:00" + version: 27.0.15 +digest: sha256:00172ce941c4d9655677a1afada15c15e77ec886c48ad59f259837c09a165547 +generated: "2026-07-15T05:58:58.740313-04:00" diff --git a/helm/redis-r3-external/Chart.yaml b/helm/redis-r3-external/Chart.yaml index 5b4425730..0c52b2bd0 100644 --- a/helm/redis-r3-external/Chart.yaml +++ b/helm/redis-r3-external/Chart.yaml @@ -26,31 +26,31 @@ appVersion: "1.17.0" dependencies: - name: redis - version: "23.1.1" + version: "27.0.15" repository: "https://charts.bitnami.com/bitnami" alias: id-id - name: redis - version: "23.1.1" + version: "27.0.15" repository: "https://charts.bitnami.com/bitnami" alias: id-eq-id - name: redis - version: "23.1.1" + version: "27.0.15" repository: "https://charts.bitnami.com/bitnami" alias: id-categories - name: redis - version: "23.1.1" + version: "27.0.15" repository: "https://charts.bitnami.com/bitnami" alias: conflation-db - name: redis - version: "23.1.1" + version: "27.0.15" repository: "https://charts.bitnami.com/bitnami" alias: semantic-count - name: redis - version: "23.1.1" + version: "27.0.15" repository: "https://charts.bitnami.com/bitnami" alias: info-content condition: info-content.enabled - name: redis - version: "23.1.1" + version: "27.0.15" repository: "https://charts.bitnami.com/bitnami" alias: chemical-drug-db diff --git a/helm/redis-r3-external/charts/redis-23.1.1.tgz b/helm/redis-r3-external/charts/redis-23.1.1.tgz deleted file mode 100644 index ad5de3814..000000000 Binary files a/helm/redis-r3-external/charts/redis-23.1.1.tgz and /dev/null differ diff --git a/helm/redis-r3-external/charts/redis-27.0.15.tgz b/helm/redis-r3-external/charts/redis-27.0.15.tgz new file mode 100644 index 000000000..af0764d59 Binary files /dev/null and b/helm/redis-r3-external/charts/redis-27.0.15.tgz differ diff --git a/helm/redis-r3-external/scripts/backup-nn-redis-db0.sh b/helm/redis-r3-external/scripts/backup-nn-redis-db0.sh index ec8489612..d353a8418 100644 --- a/helm/redis-r3-external/scripts/backup-nn-redis-db0.sh +++ b/helm/redis-r3-external/scripts/backup-nn-redis-db0.sh @@ -5,8 +5,8 @@ # # Configuration -NN_VERSION="${NN_VERSION:-2025sep1}" -NN_NAMESPACE="${NN_NAMESPACE:-translator-dev}" +NN_VERSION="${NN_VERSION:-2025nov4}" +NN_NAMESPACE="${NN_NAMESPACE:-translator-exp}" RETRIES=10 # Copy all the dump files. @@ -22,7 +22,9 @@ function check_and_download() { echo Checking RDB file. kubectl exec -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0" -- bash -c 'redis-check-rdb /data/dump.rdb' # Backup file. - kubectl cp -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0:/data/compressed.rdb.gz" ./$name.rdb.gz --retries $RETRIES + kubectl cp -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0:/data/dump.rdb" ./$name.rdb --retries $RETRIES && \ + md5 ./$name.rdb && \ + gzip ./$name.rdb } # Download files diff --git a/helm/redis-r3-external/scripts/backup-nn-redis-db1.sh b/helm/redis-r3-external/scripts/backup-nn-redis-db1.sh index cb67f9dda..34307dafb 100644 --- a/helm/redis-r3-external/scripts/backup-nn-redis-db1.sh +++ b/helm/redis-r3-external/scripts/backup-nn-redis-db1.sh @@ -5,8 +5,8 @@ # # Configuration -NN_VERSION="${NN_VERSION:-2025sep1}" -NN_NAMESPACE="${NN_NAMESPACE:-translator-dev}" +NN_VERSION="${NN_VERSION:-2025nov4}" +NN_NAMESPACE="${NN_NAMESPACE:-translator-exp}" # Copy all the dump files. function check_and_download() { @@ -21,7 +21,9 @@ function check_and_download() { echo Checking RDB file. kubectl exec -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0" -- bash -c 'redis-check-rdb /data/dump.rdb' # Backup file. - kubectl cp -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0:/data/compressed.rdb.gz" ./$name.rdb.gz --retries 10 + kubectl cp -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0:/data/dump.rdb" ./$name.rdb --retries 10 && \ + md5 ./$name.rdb && \ + gzip ./$name.rdb } # Download files diff --git a/helm/redis-r3-external/scripts/backup-nn-redis-db2-5-6.sh b/helm/redis-r3-external/scripts/backup-nn-redis-db2-5-6.sh index f70d86c71..7c767be6a 100644 --- a/helm/redis-r3-external/scripts/backup-nn-redis-db2-5-6.sh +++ b/helm/redis-r3-external/scripts/backup-nn-redis-db2-5-6.sh @@ -5,8 +5,8 @@ # # Configuration -NN_VERSION="${NN_VERSION:-2025sep1}" -NN_NAMESPACE="${NN_NAMESPACE:-translator-dev}" +NN_VERSION="${NN_VERSION:-2025nov4}" +NN_NAMESPACE="${NN_NAMESPACE:-translator-exp}" # Copy all the dump files. function check_and_download() { diff --git a/helm/redis-r3-external/scripts/backup-nn-redis-db3.sh b/helm/redis-r3-external/scripts/backup-nn-redis-db3.sh index ee1accef3..c82d02b86 100644 --- a/helm/redis-r3-external/scripts/backup-nn-redis-db3.sh +++ b/helm/redis-r3-external/scripts/backup-nn-redis-db3.sh @@ -5,8 +5,8 @@ # # Configuration -NN_VERSION="${NN_VERSION:-2025sep1}" -NN_NAMESPACE="${NN_NAMESPACE:-translator-dev}" +NN_VERSION="${NN_VERSION:-2025nov4}" +NN_NAMESPACE="${NN_NAMESPACE:-translator-exp}" # Copy all the dump files. function check_and_download() { @@ -21,7 +21,9 @@ function check_and_download() { echo Checking RDB file. kubectl exec -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0" -- bash -c 'redis-check-rdb /data/dump.rdb' # Backup file. - kubectl cp -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0:/data/compressed.rdb.gz" ./$name.rdb.gz --retries 10 + kubectl cp -n "$NN_NAMESPACE" "nn-redis-$NN_VERSION-$name-master-0:/data/dump.rdb" ./$name.rdb --retries 10 && \ + md5 ./$name.rdb && \ + gzip ./$name.rdb } # Download files diff --git a/helm/redis-r3-external/scripts/backup-nn-redis-db4.sh b/helm/redis-r3-external/scripts/backup-nn-redis-db4.sh index b06143c05..77dba67fa 100644 --- a/helm/redis-r3-external/scripts/backup-nn-redis-db4.sh +++ b/helm/redis-r3-external/scripts/backup-nn-redis-db4.sh @@ -5,8 +5,8 @@ # # Configuration -NN_VERSION="${NN_VERSION:-2025sep1}" -NN_NAMESPACE="${NN_NAMESPACE:-translator-dev}" +NN_VERSION="${NN_VERSION:-2025nov4}" +NN_NAMESPACE="${NN_NAMESPACE:-translator-exp}" # Copy all the dump files. function check_and_download() { diff --git a/helm/redis-r3-external/scripts/backup-nn-redis.sh b/helm/redis-r3-external/scripts/backup-nn-redis.sh index 40d1f36cd..4d5c7362b 100644 Binary files a/helm/redis-r3-external/scripts/backup-nn-redis.sh and b/helm/redis-r3-external/scripts/backup-nn-redis.sh differ diff --git a/helm/redis-r3-external/values.yaml b/helm/redis-r3-external/values.yaml index 698ee63f3..4a6c3950f 100644 --- a/helm/redis-r3-external/values.yaml +++ b/helm/redis-r3-external/values.yaml @@ -19,7 +19,13 @@ id-id: livenessProbe: enabled: false extraFlags: - - "--save 300 1000000" + # No automatic RDB snapshots. Persistence is explicit: mode:load disables + # saves at runtime and BGSAVEs manually at the end; mode:restore BGSAVEs and + # waits for completion at the end of run_pipe.sh. An automatic `save` policy + # can't fire only after a populate finishes without also forking repeatedly + # *during* it, which is pure copy-on-write waste on these large DBs. See the + # NodeNorm documentation/Loader.md. + - '--save ""' - "--appendonly no" replica: @@ -45,7 +51,13 @@ id-categories: livenessProbe: enabled: false extraFlags: - - "--save 300 1000000" + # No automatic RDB snapshots. Persistence is explicit: mode:load disables + # saves at runtime and BGSAVEs manually at the end; mode:restore BGSAVEs and + # waits for completion at the end of run_pipe.sh. An automatic `save` policy + # can't fire only after a populate finishes without also forking repeatedly + # *during* it, which is pure copy-on-write waste on these large DBs. See the + # NodeNorm documentation/Loader.md. + - '--save ""' - "--appendonly no" replica: @@ -71,7 +83,13 @@ id-eq-id: livenessProbe: enabled: false extraFlags: - - "--save 300 1000000" + # No automatic RDB snapshots. Persistence is explicit: mode:load disables + # saves at runtime and BGSAVEs manually at the end; mode:restore BGSAVEs and + # waits for completion at the end of run_pipe.sh. An automatic `save` policy + # can't fire only after a populate finishes without also forking repeatedly + # *during* it, which is pure copy-on-write waste on these large DBs. See the + # NodeNorm documentation/Loader.md. + - '--save ""' - "--appendonly no" replica: replicaCount: 0 @@ -96,7 +114,13 @@ semantic-count: livenessProbe: enabled: false extraFlags: - - "--save 300 1000000" + # No automatic RDB snapshots. Persistence is explicit: mode:load disables + # saves at runtime and BGSAVEs manually at the end; mode:restore BGSAVEs and + # waits for completion at the end of run_pipe.sh. An automatic `save` policy + # can't fire only after a populate finishes without also forking repeatedly + # *during* it, which is pure copy-on-write waste on these large DBs. See the + # NodeNorm documentation/Loader.md. + - '--save ""' - "--appendonly no" replica: replicaCount: 0 @@ -121,7 +145,13 @@ conflation-db: livenessProbe: enabled: false extraFlags: - - "--save 300 1000000" + # No automatic RDB snapshots. Persistence is explicit: mode:load disables + # saves at runtime and BGSAVEs manually at the end; mode:restore BGSAVEs and + # waits for completion at the end of run_pipe.sh. An automatic `save` policy + # can't fire only after a populate finishes without also forking repeatedly + # *during* it, which is pure copy-on-write waste on these large DBs. See the + # NodeNorm documentation/Loader.md. + - '--save ""' - "--appendonly no" replica: replicaCount: 0 @@ -131,14 +161,17 @@ info-content: enabled: true master: persistence: - size: 500Mi + # In NodeNorm 2.5, we add the preferred names to this database. It will probably end up being bigger than + # id-categories (same number of keys, but longer strings than a Biolink type), but as of 2025jul15 it is + # about 58G max memory. + size: 200Gi resources: limits: - cpu: 150m - memory: 500Mi + cpu: 1500m + memory: 100Gi requests: - cpu: 50m - memory: 250Mi + cpu: 500m + memory: 70Gi readinessProbe: enabled: false startupProbe: @@ -146,7 +179,13 @@ info-content: livenessProbe: enabled: false extraFlags: - - "--save 300 1000000" + # No automatic RDB snapshots. Persistence is explicit: mode:load disables + # saves at runtime and BGSAVEs manually at the end; mode:restore BGSAVEs and + # waits for completion at the end of run_pipe.sh. An automatic `save` policy + # can't fire only after a populate finishes without also forking repeatedly + # *during* it, which is pure copy-on-write waste on these large DBs. See the + # NodeNorm documentation/Loader.md. + - '--save ""' - "--appendonly no" replica: replicaCount: 0 @@ -171,7 +210,13 @@ chemical-drug-db: livenessProbe: enabled: false extraFlags: - - "--save 300 1000000" + # No automatic RDB snapshots. Persistence is explicit: mode:load disables + # saves at runtime and BGSAVEs manually at the end; mode:restore BGSAVEs and + # waits for completion at the end of run_pipe.sh. An automatic `save` policy + # can't fire only after a populate finishes without also forking repeatedly + # *during* it, which is pure copy-on-write waste on these large DBs. See the + # NodeNorm documentation/Loader.md. + - '--save ""' - "--appendonly no" replica: replicaCount: 0