Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reading from a non-existent database causes the client to send many BatchCreateSessions RPCs #768

Closed
sebright opened this issue Jan 5, 2021 · 1 comment · Fixed by #784
Assignees
Labels
api: spanner Issues related to the googleapis/java-spanner API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@sebright
Copy link
Contributor

sebright commented Jan 5, 2021

I noticed that reads to a non-existent database can be very slow to fail. I looked into the issue further and found that the client continues to send BatchCreateSessions RPCs after the read fails, so the additional BatchCreateSessions RPCs may be the cause of the slowness.

google-cloud-spanner: 3.1.2 and HEAD
grpc-java: 1.34.0

Reproducing slow reads

When I ran this test, the reads started out taking about 300 milliseconds. After five minutes, the logging showed that the reads had slowed down to about ten seconds.

import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.InstanceConfigId;
import com.google.cloud.spanner.InstanceId;
import com.google.cloud.spanner.InstanceInfo;
import com.google.cloud.spanner.Key;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerOptions;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;

public class BatchCreateSessionsTest {
  private static final Logger logger = Logger.getLogger(BatchCreateSessionsTest.class.getName());

  @Test
  public void testBatchCreateSessions() throws Exception {
    Spanner spanner = SpannerOptions.getDefaultInstance().getService();
    String projectId = spanner.getOptions().getProjectId();
    InstanceId instanceId = InstanceId.of(projectId, "my-instance");
    InstanceConfigId instanceConfigId = InstanceConfigId.of(projectId, "regional-us-central1");
    spanner
        .getInstanceAdminClient()
        .createInstance(
            InstanceInfo.newBuilder(instanceId)
                .setInstanceConfigId(instanceConfigId)
                .setDisplayName("my-instance")
                .setNodeCount(1)
                .build())
        .get();
    DatabaseId databaseId = DatabaseId.of(instanceId, "my-database");

    while (true) {
      Instant start = Instant.now();
      try {
        spanner
            .getDatabaseClient(databaseId)
            .singleUse()
            .readRow("MyTable", Key.of(0), Arrays.asList("MyColumn"));
      } catch (Exception e) {
        logger.log(Level.INFO, e.getMessage());
      } finally {
        Instant end = Instant.now();
        logger.log(Level.INFO, "Duration: " + Duration.between(start, end));
      }
    }
  }
}

Reproducing excessive calls to BatchCreateSessions

I initially noticed the high rate of BatchCreateSessions RPCs in OpenCensus RPC stats. However, I simplified the reproduction to avoid OpenCensus and issue #202 by instead adding a log statement before

. Then I modified the test case above with this diff:

@@ -30,21 +30,18 @@ public class BatchCreateSessionsTest {
                 .setNodeCount(1)
                 .build())
         .get();
     DatabaseId databaseId = DatabaseId.of(instanceId, "my-database");
 
-    while (true) {
-      Instant start = Instant.now();
+    for (int i = 0; i < 2; i++) {
       try {
         spanner
             .getDatabaseClient(databaseId)
             .singleUse()
             .readRow("MyTable", Key.of(0), Arrays.asList("MyColumn"));
       } catch (Exception e) {
         logger.log(Level.INFO, e.getMessage());
-      } finally {
-        Instant end = Instant.now();
-        logger.log(Level.INFO, "Duration: " + Duration.between(start, end));
       }
     }
+    Thread.sleep(300_000);
   }
 }

The output seems to show that the client sends one BatchCreateSessions RPC every ten seconds for each failed read:

Running BatchCreateSessionsTest
Jan 04, 2021 10:14:37 PM com.google.auth.oauth2.DefaultCredentialsProvider warnAboutProblematicCredentials
WARNING: Your application has authenticated using end user credentials from Google Cloud SDK. We recommend that most server applications use service accounts instead. If your application continues to use end user credentials from Cloud SDK, you might receive a "quota exceeded" or "API not enabled" error. For more information about service accounts, see https://cloud.google.com/docs/authentication/.
Jan 04, 2021 10:14:58 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:58 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:58 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:58 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:59 PM BatchCreateSessionsTest testBatchCreateSessions
INFO: NOT_FOUND: com.google.api.gax.rpc.NotFoundException: io.grpc.StatusRuntimeException: NOT_FOUND: Database not found: projects/<project-id>/instances/my-instance/databases/my-database
resource_type: "type.googleapis.com/google.spanner.admin.database.v1.Database"
resource_name: "projects/<project-id>/instances/my-instance/databases/my-database"
description: "Database does not exist."

Jan 04, 2021 10:14:59 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:59 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:59 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:59 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=25
Jan 04, 2021 10:14:59 PM BatchCreateSessionsTest testBatchCreateSessions
INFO: NOT_FOUND: com.google.api.gax.rpc.NotFoundException: io.grpc.StatusRuntimeException: NOT_FOUND: Database not found: projects/<project-id>/instances/my-instance/databases/my-database
resource_type: "type.googleapis.com/google.spanner.admin.database.v1.Database"
resource_name: "projects/<project-id>/instances/my-instance/databases/my-database"
description: "Database does not exist."

Jan 04, 2021 10:15:08 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:09 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:18 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:19 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:28 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:29 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:38 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:39 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:48 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:49 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:58 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:15:59 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:16:08 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
Jan 04, 2021 10:16:09 PM com.google.cloud.spanner.SessionClient internalBatchCreateSessions
INFO: Calling BatchCreateSessions with sessionCount=100
...
@product-auto-label product-auto-label bot added the api: spanner Issues related to the googleapis/java-spanner API. label Jan 5, 2021
@yoshi-automation yoshi-automation added the triage me I really want to be triaged. label Jan 6, 2021
@skuruppu skuruppu added type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. priority: p2 Moderately-important priority. Fix may not be included in next release. and removed triage me I really want to be triaged. labels Jan 6, 2021
@sebright
Copy link
Contributor Author

@thiagotnunes Thanks for the fix!

ansh0l pushed a commit to ansh0l/java-spanner that referenced this issue Nov 10, 2022
This is an auto-generated regeneration of the .pb.go files by
cloud.google.com/go/internal/gapicgen. Once this PR is submitted, genbot will
update the corresponding PR to depend on the newer version of go-genproto, and
assign reviewers. Whilst this or any regen PR is open in go-genproto, genbot
will not create any more regeneration PRs. If all regen PRs are closed,
gapicgen will create a new set of regeneration PRs once per night.

If you have been assigned to review this PR, please:

- Ensure that CI is passing. If it's failing, it requires your manual attention.
- Approve and submit this PR if you believe it's ready to ship. That will prompt
genbot to assign reviewers to the google-cloud-go PR.

There is no corresponding google-cloud-go PR.

Changes:

docs(dialogflow/cx): updated copyright
  PiperOrigin-RevId: 431547560
  Source-Link: googleapis/googleapis@8df2b3a

chore: regenerate API index

  Source-Link: googleapis/googleapis@e9e3c1b

feat: Added Service Controller v2 API
  PiperOrigin-RevId: 431525317
  Source-Link: googleapis/googleapis@43930af
rajatbhatta pushed a commit to rajatbhatta/java-spanner that referenced this issue Nov 17, 2022
* chore: update github actions

* chore: update
Source-Link: googleapis/synthtool@1622741
Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-java:latest@sha256:e3746f84955528d0fe24bf2e4df89875d6ce5a036af01b9c326d61a38838523a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the googleapis/java-spanner API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants