הפעלת PGAdapter

בדף הזה מוסבר איך להפעיל את PGAdapter ב-Spanner. מידע נוסף על PGAdapter זמין במאמר מידע על PGAdapter. כדי לקבל את קובץ ה-PGAdapter הבינארי, אפשר לעיין במאמר בנושא קבלת PGAdapter.

אפשר להפעיל את PGAdapter בדרכים הבאות:

  • כתהליך עצמאי
  • בתוך קונטיינר Docker
  • ב-Cloud Run
  • שימוש ב-PGAdapter כפרוקסי sidecar (לדוגמה, באשכול Kubernetes)
  • בתוך האפליקציה שלכם ב-Java

לפני שמתחילים

לפני שמפעילים את PGAdapter, צריך לוודא שעברתם אימות באמצעות חשבון משתמש או חשבון שירות במכונה שבה PGAdapter יפעל. אם אתם משתמשים בחשבון שירות, אתם צריכים לדעת את המיקום של קובץ מפתח ה-JSON (קובץ פרטי הכניסה). אחר כך אפשר לציין את נתיב פרטי הכניסה באמצעות האפשרות -c של PGAdapter או באמצעות הגדרת משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS.

למידע נוסף:

בחירת שיטה להפעלת PGAdapter

אפשר להפעיל את PGAdapter כתהליך עצמאי, בתוך קונטיינר של Docker, ב-Cloud Run או בתהליך עם אפליקציית Java. כשמפעילים את PGAdapter, מציינים את הפרויקט, את מזהה מופע Spanner ואת מסד הנתונים שאליו רוצים להתחבר. אפשר גם לציין את הנתיב לקובץ פרטי כניסה בפורמט JSON (קובץ מפתח).

עצמאי

מורידים את PGAdapter באמצעות הפקודה הבאה.

    wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz \
    && tar -xzvf pgadapter.tar.gz
    

מריצים את הפקודה הבאה כדי להפעיל את PGAdapter.

    java -jar pgadapter.jar -p PROJECT_ID -i INSTANCE_ID -d DATABASE_ID \
    -c CREDENTIALS_FILE_PATH \
    ADDITIONAL_OPTIONS
    

חובה לציין את האפשרויות הבאות:

-p project_id
מזהה הפרויקט שבו פועל מסד הנתונים של Spanner.
-i instance_id
מזהה מכונת Spanner.
-d database_ID
המזהה של מסד הנתונים ב-Spanner שאליו רוצים להתחבר.

האפשרויות הבאות הן אופציונליות:

-r databaseRole=database_role
תפקיד במסד הנתונים שבו ייעשה שימוש בסשן.
מידע נוסף על הרשאות עם PGAdapter
-c credentials_file_path
הנתיב המלא לקובץ המפתחות שמכיל את פרטי הכניסה של חשבון השירות בפורמט JSON. אם האפשרות הזו לא מוגדרת, פרטי הכניסה נקראים מהנתיב שצוין על ידי משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS.

במאמר יצירת חשבון שירות מוסבר איך יוצרים חשבון שירות ומורידים קובץ מפתח בפורמט JSON.

מוודאים שחשבון השירות קיבל מספיק פרטי כניסה כדי לגשת למסד הנתונים.

אפשר להשמיט את האפשרות הזו אם קודם מאמתים את ה-CLI של Google Cloud באמצעות הפקודה הבאה:

gcloud auth application-default login

מידע נוסף זמין במאמר הגדרת אימות והרשאה.

-s port
היציאה ש-PGAdapter מאזין לה. ברירת המחדל היא 5432 (יציאת ברירת המחדל של PostgreSQL).
-v version_number

מספר הגרסה של PostgreSQL שיוצג ללקוח במהלך החיבור. ערך ברירת המחדל הוא 14.1.

חלק מהאפליקציות ומנהלי ההתקנים של PostgreSQL מאפשרים תכונות נוספות בהתאם למספר הגרסה הזה. יכול להיות ש-Spanner לא תומך בתכונות האלה. רשימה מלאה של לקוחות נתמכים מופיעה במאמר Drivers and Clients.

-x

הפעלת חיבורים ממארחים אחרים מלבד localhost. אל תשתמשו באפשרות כשמפעילים את PGAdapter במצב עצמאי. אפשר להשתמש רק ב-כשמתחילים בתוך קונטיינר Docker.

כברירת מחדל, כאמצעי אבטחה, PGAdapter מקבל חיבורים רק מ-localhost.

בדוגמה הבאה מפעילים את PGAdapter במצב עצמאי ביציאה 5432 באמצעות פרטי הכניסה שמוגדרים כברירת מחדל לאפליקציה.

java -jar pgadapter.jar \
-p my-project \
-i my-instance \
-d my-database \
-s 5432

Docker

מריצים את הפקודה הבאה כדי להפעיל את PGAdapter.

docker run -d -p HOST-PORT:DOCKER-PORT \
-v CREDENTIALS_FILE_PATH:/acct_credentials.json \
gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
-p PROJECT_ID -i INSTANCE_ID -d DATABASE_ID  \
-c /acct_credentials.json -x OTHER_PGAdapter_OPTIONS

בנוסף לאפשרויות של PGAdapter לציון פרויקט, מופע, מסד נתונים ופרטי כניסה, נדרשות האפשרויות הבאות:

-p 127.0.0.1:HOST-PORT:DOCKER-PORT

אפשרות Docker הזו ממפה את הפורט DOCKER-PORT בתוך מאגר Docker לפורט HOST-PORT מחוץ למאגר. הערך של DOCKER-PORT צריך להיות זהה להגדרה של PGAdapter בתוך הקונטיינר. ברירת המחדל היא 5432. ‫HOST-PORT היא היציאה ש-Docker צריך להאזין לה מחוץ לקונטיינר כדי לקבל בקשות לחיבור. היציאה צריכה להיות תמיד זמינה ב-localhost.

מידע נוסף זמין במאמר Publish or expose port (-p, --expose) (פרסום או חשיפה של יציאה (‎-p, --expose)) במאמרי העזרה של Docker.

-v CREDENTIALS_FILE_PATH:in_container_mount_point

אפשרות Docker הזו מבצעת bind mount של נפח אחסון משותף. היא ממפה את הנתיב של המארח מחוץ לקונטיינר לנפח (נקודת טעינה) בתוך הקונטיינר. הנתיבים של המארח והקונטיינר מופרדים בנקודתיים (:).

האפשרות הזו מאפשרת ל-PGAdapter לגשת לקובץ פרטי הכניסה בפורמט JSON שנמצא מחוץ לקונטיינר. בדוגמה שלמעלה, האפשרות -c מפנה לנקודת הטעינה ב-container. בדוגמה הזו, שם נקודת הטעינה בתוך הקונטיינר הוא /acct_credentials.json. אתם יכולים לתת לו כל שם שתרצו.

מידע נוסף זמין במאמר בנושא VOLUME (מערכות קבצים משותפות) במסמכי התיעוד של Docker.

-x

הפעלת חיבורים ממארחים אחרים מלבד localhost. הפעולה הזו נדרשת כי היציאה בתוך הקונטיינר שממופה ליציאת המארח לא מופיעה ב-PGAdapter כמארח מקומי.

האפשרויות הבאות הן אופציונליות:

-r databaseRole=database_role
תפקיד במסד הנתונים שבו ייעשה שימוש בסשן.
מידע נוסף זמין במאמר בנושא הרשאה באמצעות PGAdapter.

בדוגמה הבאה, יציאת Docker ויציאת המארח מוגדרות שתיהן ליציאת ברירת המחדל של שירות מסד הנתונים PostgreSQL,‏ 5432.

docker run -d -p 127.0.0.1:5432:5432 \
-v /tmp/credentials.json:/acct_credentials.json \
gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
-p my_project -i my_instance -d my_database \
-c /acct_credentials.json -x

Cloud Run

אי אפשר לפרוס את PGAdapter כשירות עצמאי ב-Cloud Run, אבל אפשר לפרוס אותו כקובץ עזר חיצוני.

מומלץ להריץ את PGAdapter בתבנית sidecar ולא להריץ אותו כשירות נפרד, מהסיבות הבאות:
  • מונעים נקודת כשל בודדת. הגישה של כל אפליקציה למסד הנתונים שלכם היא נפרדת, ולכן האפליקציות עמידות יותר.
  • מספר המופעים של PGAdapter גדל באופן אוטומטי ביחס ישר למספר המופעים של האפליקציה.

במאגר PGAdapter GitHub יש כמה אפליקציות לדוגמה שפועלות באמצעות Cloud Run ו-PGAdapter כקובץ עזר חיצוני לשפות תכנות שונות.

קובץ התצורה הבא מראה איך להוסיף את PGAdapter כקובץ עזר חיצוני ל-Cloud Run:

  apiVersion: serving.knative.dev/v1
  kind: Service
  metadata:
  annotations:
    # This example uses an in-memory volume for Unix domain sockets.
    # This is a Cloud Run beta feature.
    run.googleapis.com/launch-stage: BETA
  name: pgadapter-sidecar-example
  spec:
  template:
    metadata:
      annotations:
        run.googleapis.com/execution-environment: gen1
        # This registers 'pgadapter' as a dependency of 'app' and ensures that pgadapter starts
        # before the app container.
        run.googleapis.com/container-dependencies: '{"app":["pgadapter"]}'
    spec:
      # Create an in-memory volume that can be used for Unix domain sockets.
      volumes:
        - name: sockets-dir
          emptyDir:
            # This directory contains the virtual socket files that are used to
            # communicate between your application and PGAdapter.
            sizeLimit: 50Mi
            medium: Memory
      containers:
        # This is the main application container.
        - name: app
          # Example: europe-north1-docker.pkg.dev/my-test-project/cloud-run-source-deploy/pgadapter-sidecar-example
          image: MY-REGION.pkg.dev/MY-PROJECT/cloud-run-source-deploy/pgadapter-sidecar-example
          # The PGADAPTER_HOST variable is set to point to /sockets, which is the shared in-memory
          # volume that is used for Unix domain sockets.
          env:
            - name: SPANNER_PROJECT
              value: my-project
            - name: SPANNER_INSTANCE
              value: my-instance
            - name: SPANNER_DATABASE
              value: my-database
            - name: PGADAPTER_HOST
              value: /sockets
            - name: PGADAPTER_PORT
              value: "5432"
          ports:
            - containerPort: 8080
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
        # This is the PGAdapter sidecar container.
        - name: pgadapter
          image: gcr.io/cloud-spanner-pg-adapter/pgadapter
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
          args:
            - -dir /sockets
            - -x
          # Add a startup probe that checks that PGAdapter is listening on port 5432.
          startupProbe:
            initialDelaySeconds: 10
            timeoutSeconds: 10
            periodSeconds: 10
            failureThreshold: 3
            tcpSocket:
              port: 5432
  

Sidecar Proxy

אפשר להשתמש ב-PGAdapter כקובץ עזר חיצוני, למשל באשכול Kubernetes. קונטיינרים מסוג Kubernetes sidecar פועלים במקביל לקונטיינר הראשי ב-Pod.

מומלץ להריץ את PGAdapter בתבנית sidecar ולא כשירות נפרד, מהסיבות הבאות:

  • מונעים נקודת כשל בודדת. הגישה של כל אפליקציה למסד הנתונים שלכם היא נפרדת מהגישה של אפליקציות אחרות, ולכן הן עמידות יותר.
  • ‫PGAdapter צורך משאבים ביחס לינארי לשימוש, ולכן הדפוס הזה מאפשר לכם להגדיר ולבקש משאבים בצורה מדויקת יותר בהתאם לצרכים של האפליקציות שלכם כשהן גדלות.

קובץ התצורה הבא מראה איך להוסיף את PGAdapter כקובץ עזר חיצוני לאשכול Kubernetes:

containers:
- name: pgadapter
image: gcr.io/cloud-spanner-pg-adapter/pgadapter
ports:
  - containerPort: 5432
args:
  - "-p my-project"
  - "-i my-instance"
  - "-d my-database"
  - "-x"
resources:
  requests:
    # PGAdapter's memory use scales linearly with the number of active
    # connections. Fewer open connections will use less memory. Adjust
    # this value based on your application's requirements.
    memory: "512Mi"
    # PGAdapter's CPU use scales linearly with the amount of IO between
    # the database and the application. Adjust this value based on your
    # application's requirements.
    cpu: "1"

במאגר PGAdapter ב-GitHub יש מדריך מפורט ואפליקציה לדוגמה. בדוגמה הזו יש הוראות לשימוש ב-איחוד זהויות של עומסי עבודה ל-GKE עם PGAdapter.

Java In-process

יוצרים מכונה של PGAdapter ומפעילים אותה באמצעות קוד Java. זו ההגדרה המומלצת לאפליקציות Java.

אם אתם משתמשים בחשבון שירות לאימות, חשוב לוודא שמשתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS מוגדר לנתיב של קובץ פרטי הכניסה.

  1. מוסיפים את google-cloud-spanner-pgadapter כתלות לפרויקט. פרטים נוספים זמינים במאמר הורדה של PGAdapter.
  2. יוצרים שרת באמצעות המחלקה com.google.cloud.spanner.pgadapter.ProxyServer.
  3. /**
    * Starts PGAdapter in-process and returns a reference to the server. Use this reference to
    * gracefully shut down the server when your application shuts down.
    *
    * @param project the Google Cloud project that PGAdapter should connect to
    * @param instance the Spanner instance that PGAdapter should connect to
    * @param credentialsFile the full path of a credentials file that PGAdapter should use, or 
    *     null if PGAdapter should use the application default credentials
    */
    static Server startPGAdapter(String project, String instance, String credentialsFile) {
    OptionsMetadata.Builder builder =
        OptionsMetadata.newBuilder()
            .setProject(project)
            .setInstance(instance)
            // Start PGAdapter on any available port.
            .setPort(0);
    if (credentialsFile != null) {
      builder.setCredentialsFile(credentialsFile);
    }
    ProxyServer server = new ProxyServer(builder.build());
    server.startServer();
    server.awaitRunning();
    
    return new PGAdapter(server);
    }

במאגר של PGAdapter ב-GitHub יש אפליקציה מלאה לדוגמה.

הנחיות להקצאת משאבים לקובץ העזר החיצוני של PGAdapter

ההנחיות הבאות יעזרו לכם להגדיר את משאבי הזיכרון והמעבד (CPU) עבור ה-proxy של PGAdapter sidecar. הערכים האופטימליים משתנים בהתאם לעומס העבודה הספציפי.

זיכרון

מכיוון ש-PGAdapter לא שומר הרבה נתונים במטמון, הוא צריך זיכרון כדי להמיר את תוצאות השאילתות מפורמט Spanner gRPC לפורמט פרוטוקול התקשורת של PostgreSQL. זה רלוונטי במיוחד לעומסי עבודה עם עמודות בינאריות גדולות, כי Spanner ו-PostgreSQL מטפלים בסוגי הנתונים האלה בצורה שונה.

כדי לקבוע כמה זיכרון להקצות, משתמשים בנוסחה הבאה להקצאת זיכרון, כאשר <var>number of concurrent connections</var> הוא מספר החיבורים בו-זמנית שהאפליקציה מטפלת בהם:

‫384MB + (2MB * number of concurrent connections)

לדוגמה, אם האפליקציה שלכם מטפלת ב-200 חיבורים בו-זמנית, הקצו בערך 784MB של זיכרון:

‫384MB + (2MB * 200) = 784MB

מתחילים עם הקצאת הזיכרון הבסיסית הזו. כדאי לעקוב אחרי השימוש בו בעומס ריאלי כדי לכוונן את הערך לפי הצרכים הספציפיים שלכם.

CPU

השימוש ב-PGAdapter לא צורך הרבה משאבי CPU. הסיבה לכך היא שהתפקיד העיקרי שלו הוא לשמש כשרת proxy למעבר נתונים. עם זאת, השימוש במעבד (CPU) גדל ככל שכמות הנתונים שנשלחים ומתקבלים גדולה יותר.

כשמקצים CPU, כדאי להביא בחשבון את הגורמים הבאים:

  • עומס עבודה: אפליקציות שמבצעות שאילתות שמחזירות כמויות גדולות של נתונים דורשות יותר כוח CPU לכל חיבור מאפליקציות שמחזירות רק כמה שורות ועמודות.
  • דפוס הגישה של האפליקציה: אם האפליקציה שלכם ניגשת ל-Spanner באופן סינכרוני, היא לא פעילה בזמן ההמתנה לנתונים מהפרוקסי. במקרה כזה, סביר להניח שהאפליקציה והפרוקסי לא יתחרו על משאבי המעבד.

מתחילים עם הקצאה בסיסית של CPU. כדאי לעקוב אחרי השימוש בו בעומס ריאלי כדי לשנות את הערך בהתאם לצרכים הספציפיים שלכם.

המאמרים הבאים