Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DatastoreからSpannerに 移行したいぞ途中編 / migrate Datastore to Spanner in progress

DatastoreからSpannerに 移行したいぞ途中編 / migrate Datastore to Spanner in progress

GCPUG Tokyo Spanner Day August 2021
https://gcpug-tokyo.connpass.com/event/220499/

DatastoreからSpannerに 移行したいぞ途中編 という話

0e797080b64e6b03ed00964cf69b5058?s=128

Masahiro Wakame

August 06, 2021
Tweet

More Decks by Masahiro Wakame

Other Decks in Programming

Transcript

  1. Datastore͔ΒSpannerʹ Ҡߦ్͍ͨͧ͠தฤ GCPUG Tokyo Spanner Day August 2021 Θ͔Ί ·͞ͻΖ

  2. Θ͔Ί ·͞ͻΖ @v vakame Masahiro Wakame GAE/Go GraphQL ٕज़ॻయ

  3. ຊ೔ͷςʔϚ •ٕज़ॻయWebΛҠߦ͍ͨ͠ʂ •Datastore→Spanner ࡞ۀதͰ͢ •ݱঢ়ͷ஌ݟ ͍ͭ׬ྃ͢Δ͔͸Θ͔ΒΜ…

  4. Ϟνϕʔγϣϯ •UNION ALLͱ͔͔ͨͬͨ͠ •ձ͕ࣾओʹSpannerͳͷͰ৮Γ͔ͨͬͨ •ίετ͕ 1/10 ʹͳͬͨͷͰݱ࣮తʹ ΫΤϦͷॊೈ͞ʹظ଴…ʂ

  5. ΞʔΩςΫνϟ1 •AppEngine/Go 1.1 5 •Datastore → Spanne r •GraphQL (gqlgen)

    GraphQLͷԸܙ͕݁ߏσΧ͍
  6. ΞʔΩςΫνϟ2 1. API (GraphQL ) 2. Service (domain ) 3.

    Repository (DB) LayeredͬΆ͍͚ͲશવͦΜͳ͜ͱͳ͍
  7. جຊํ਑ •Datastore༻RepositoryΛࠩ͠ସ͑ •؀ڥม਺Ͱ੾Γସ͑ •Spanner friendlyͳมߋ͸ೖΕͳ͍ ·ͣ͸΍Γ͖Γ͍ͨ

  8. ਐḿ •શRepositoryͷSpanner൛ͷ࡞੒׬ •Datastore,SpannerͰಉ͡ςετ͕௨ͬͨ •؀ڥ੔උ΍σʔλҠߦݕ౼͸͜Ε͔Β ંΓฦͨ͠ײ͸͋Δ

  9. Tips ຊ೔ͷຊ୊Ͱ͢

  10. ओு •OpenCensusͷTrace͸େࣄʂʂʂ

  11. Spanner Emulator •ศར CIͰ࢖ͬͯ·͢ •ReadWriteTransaction͕ෳ਺షΕͳ͍ •͜ͷ੍໿͕݁ߏΩπ͍ʂ •spanner.Client#Apply ΋ྫ֎͡Όͳ͍ ApplyAtLeastOnce΋ͩΊ

  12. Ͳ͏ͳΔʁ •ΤϥʔʹͳΔ •Timeout·ͰϦτϥΠ͢Δ •ΞϓϦ͔ΒΤϥʔݟ͑ͳ͍ ී௨ʹ਺༹͚࣌ؒ·͢

  13. ରࡦ •Google͸OpenCensus࢖ͬͯΔ •https://bit.ly/37qymo W •Open CensusͷTraceϩάΛݟΔͱ݁ߏ ৭ʑग़ͯΔ…ʂʂ Spanner Clientͷίʔυࣗମ΋ࢀߟʹͳΓ·͢

  14. ΍ͬͯΈͨ Traceࠐͷ࣮ߦ݁Ռ 2021-08-05T10:42:25.1409165Z === RUN TestSpanne r 2021-08-05T10:42:25.2019180Z 2021/08/05 10:42:25

    Duration: 68.2807ms Name: google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2030092Z ParentSpanID: 66d0f65276a786dc SpanID: 41a185b1034c5e57 ChildSpanCount: 0 2021-08-05T10:42:25.2034069Z INFO: create spanner client with projects/tbf-test/instances/tbf-test-instance/databases/for-ut-a76 3 2021-08-05T10:42:25.2035431Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_utils.go:7 0 2021-08-05T10:42:25.2037531Z 2021/08/05 10:42:25 Duration: 179.701µs Name: cloud.google.com/go/spanner.NewClient Code: 0 Message: Attributes: map[] Annotations: [ ] 2021-08-05T10:42:25.2038616Z ParentSpanID: 66d0f65276a786dc SpanID: 1c72141091f035d2 ChildSpanCount: 0 2021-08-05T10:42:25.2050051Z 2021/08/05 10:42:25 Duration: 2.842616ms Name: google.spanner.v1.Spanner.BatchCreateSessions Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2051837Z ParentSpanID: d21332cdab39e5c7 SpanID: ade4c02b39debc42 ChildSpanCount: 0 2021-08-05T10:42:25.2054728Z 2021/08/05 10:42:25 Duration: 2.925417ms Name: cloud.google.com/go/spanner.BatchCreateSessions Code: 0 Message: Attributes: map[] Annotations: [***Time:2021-08-05 10:42:25.201796419 +0000 UTC m=+157.694579279 Message:Creating a batch of 2 sessions Attributes:map[]*** ***Time:2021-08-05 10:42:25.204703536 +0000 UTC m=+157.697486496 Message:Received a batch of 2 sessions Attributes:map[]*** ***Time:2021-08-05 10:42:25.204718536 +0000 UTC m=+157.697501396 Message:Finished creating 2 sessions Attributes:map[]*** ] 2021-08-05T10:42:25.2056889Z ParentSpanID: 0000000000000000 SpanID: d21332cdab39e5c7 ChildSpanCount: 1 2021-08-05T10:42:25.2058866Z 2021/08/05 10:42:25 Duration: 410.303µs Name: google.spanner.v1.Spanner.BeginTransaction Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2060645Z ParentSpanID: f742a36e1e950d4d SpanID: 88b54f8ac68294bd ChildSpanCount: 0 2021-08-05T10:42:25.2061510Z INFO: before ReadRo w 2021-08-05T10:42:25.2062577Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_test.go:2 0 2021-08-05T10:42:25.2064464Z 2021/08/05 10:42:25 Duration: 9.8µs Name: cloud.google.com/go/spanner.Read Code: 0 Message: Attributes: map[] Annotations: [ ] 2021-08-05T10:42:25.2065690Z ParentSpanID: f742a36e1e950d4d SpanID: 6386dee853276c38 ChildSpanCount: 1 2021-08-05T10:42:25.2067399Z 2021/08/05 10:42:25 Duration: 555.803µs Name: google.spanner.v1.Spanner.StreamingRead Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2069446Z ParentSpanID: 3e576d47e1cb43b3 SpanID: 1928fca56e701b2e ChildSpanCount: 0 2021-08-05T10:42:25.2071376Z 2021/08/05 10:42:25 Duration: 748.605µs Name: cloud.google.com/go/spanner.RowIterator Code: 0 Message: Attributes: map[] Annotations: [ ] 2021-08-05T10:42:25.2072630Z ParentSpanID: 6386dee853276c38 SpanID: 3e576d47e1cb43b3 ChildSpanCount: 1 2021-08-05T10:42:25.2074888Z WARNING: err: spanner: code = "NotFound", desc = "row not found(Table: Organization, PrimaryKey: (\"111\")) " 2021-08-05T10:42:25.2076611Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_test.go:2 9 2021-08-05T10:42:25.2078426Z INFO: before Apply with ApplyAtLeastOnc e 2021-08-05T10:42:25.2081087Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_test.go:4 9 2021-08-05T10:42:25.2084536Z 2021/08/05 10:42:25 Duration: 533.803µs Name: google.spanner.v1.Spanner.Commit Code: 10 Message: Transaction 2 aborted due to active transaction 1. The emulator only supports one transaction at a time. Some best practices to avoid ABORT errors in Cloud Spanner service are : 2021-08-05T10:42:25.2087265Z 1. Avoid use of nested transactions . 2021-08-05T10:42:25.2088255Z 2. Explicitly Rollback failed transactions . 2021-08-05T10:42:25.2090414Z 3. All transactions should be running inside of retry loops . 2021-08-05T10:42:25.2091644Z Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2092587Z ParentSpanID: f4f88a04fc14f3a8 SpanID: cfc9196389b9ca23 ChildSpanCount: 0
  15. ΍ͬͯΈͨ ͦͯ͠Timeout΁… 2021-08-05T10:42:25.1409165Z === RUN TestSpanne r 2021-08-05T10:42:25.2019180Z 2021/08/05 10:42:25

    Duration: 68.2807ms Name: google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2030092Z ParentSpanID: 66d0f65276a786dc SpanID: 41a185b1034c5e57 ChildSpanCount: 0 2021-08-05T10:42:25.2034069Z INFO: create spanner client with projects/tbf-test/instances/tbf-test-instance/databases/for-ut-a76 3 2021-08-05T10:42:25.2035431Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_utils.go:7 0 2021-08-05T10:42:25.2037531Z 2021/08/05 10:42:25 Duration: 179.701µs Name: cloud.google.com/go/spanner.NewClient Code: 0 Message: Attributes: map[] Annotations: [ ] 2021-08-05T10:42:25.2038616Z ParentSpanID: 66d0f65276a786dc SpanID: 1c72141091f035d2 ChildSpanCount: 0 2021-08-05T10:42:25.2050051Z 2021/08/05 10:42:25 Duration: 2.842616ms Name: google.spanner.v1.Spanner.BatchCreateSessions Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2051837Z ParentSpanID: d21332cdab39e5c7 SpanID: ade4c02b39debc42 ChildSpanCount: 0 2021-08-05T10:42:25.2054728Z 2021/08/05 10:42:25 Duration: 2.925417ms Name: cloud.google.com/go/spanner.BatchCreateSessions Code: 0 Message: Attributes: map[] Annotations: [***Time:2021-08-05 10:42:25.201796419 +0000 UTC m=+157.694579279 Message:Creating a batch of 2 sessions Attributes:map[]*** ***Time:2021-08-05 10:42:25.204703536 +0000 UTC m=+157.697486496 Message:Received a batch of 2 sessions Attributes:map[]*** ***Time:2021-08-05 10:42:25.204718536 +0000 UTC m=+157.697501396 Message:Finished creating 2 sessions Attributes:map[]*** ] 2021-08-05T10:42:25.2056889Z ParentSpanID: 0000000000000000 SpanID: d21332cdab39e5c7 ChildSpanCount: 1 2021-08-05T10:42:25.2058866Z 2021/08/05 10:42:25 Duration: 410.303µs Name: google.spanner.v1.Spanner.BeginTransaction Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2060645Z ParentSpanID: f742a36e1e950d4d SpanID: 88b54f8ac68294bd ChildSpanCount: 0 2021-08-05T10:42:25.2061510Z INFO: before ReadRo w 2021-08-05T10:42:25.2062577Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_test.go:2 0 2021-08-05T10:42:25.2064464Z 2021/08/05 10:42:25 Duration: 9.8µs Name: cloud.google.com/go/spanner.Read Code: 0 Message: Attributes: map[] Annotations: [ ] 2021-08-05T10:42:25.2065690Z ParentSpanID: f742a36e1e950d4d SpanID: 6386dee853276c38 ChildSpanCount: 1 2021-08-05T10:42:25.2067399Z 2021/08/05 10:42:25 Duration: 555.803µs Name: google.spanner.v1.Spanner.StreamingRead Code: 0 Message: Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2069446Z ParentSpanID: 3e576d47e1cb43b3 SpanID: 1928fca56e701b2e ChildSpanCount: 0 2021-08-05T10:42:25.2071376Z 2021/08/05 10:42:25 Duration: 748.605µs Name: cloud.google.com/go/spanner.RowIterator Code: 0 Message: Attributes: map[] Annotations: [ ] 2021-08-05T10:42:25.2072630Z ParentSpanID: 6386dee853276c38 SpanID: 3e576d47e1cb43b3 ChildSpanCount: 1 2021-08-05T10:42:25.2074888Z WARNING: err: spanner: code = "NotFound", desc = "row not found(Table: Organization, PrimaryKey: (\"111\")) " 2021-08-05T10:42:25.2076611Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_test.go:2 9 2021-08-05T10:42:25.2078426Z INFO: before Apply with ApplyAtLeastOnc e 2021-08-05T10:42:25.2081087Z /home/runner/work/TechBookFestWeb/TechBookFestWeb/server/domains/spanner_test.go:4 9 2021-08-05T10:42:25.2084536Z 2021/08/05 10:42:25 Duration: 533.803µs Name: google.spanner.v1.Spanner.Commit Code: 10 Message: Transaction 2 aborted due to active transaction 1. The emulator only supports one transaction at a time. Some best practices to avoid ABORT errors in Cloud Spanner service are : 2021-08-05T10:42:25.2087265Z 1. Avoid use of nested transactions . 2021-08-05T10:42:25.2088255Z 2. Explicitly Rollback failed transactions . 2021-08-05T10:42:25.2090414Z 3. All transactions should be running inside of retry loops . 2021-08-05T10:42:25.2091644Z Attributes: map[Client:true FailFast:true] Annotations: [ ] 2021-08-05T10:42:25.2092587Z ParentSpanID: f4f88a04fc14f3a8 SpanID: cfc9196389b9ca23 ChildSpanCount: 0
  16. Ͳ͏΍Δʁ •ςετͷͱ͖͚ͩTraceΛstdoutʹग़ྗ͢ ΔExporterΛ࢖͏ ͱͬͯ΋؆୯

  17. TextTraceExporter ͜Μ͚ͩ type textTraceExporter struct{ } var _ trace.Exporter =

    (*textTraceExporter)(nil ) func NewTextTraceExporter() trace.Exporter { return &textTraceExporter{ } } func (exporter *textTraceExporter) ExportSpan(sd *trace.SpanData) { if os.Getenv("DUMP_TEST_TRACE") != "TRUE" { retur n } if sd == nil { retur n } rawlog.Printf ( "Duration: %s Name: %s Code: %d Message: %s Attributes: %+v Annotations: %+v\n\tParentSpanID: %s SpanID: %s ChildSpanCount: %d" , sd.EndTime.Sub(sd.StartTime), sd.Name, sd.Code, sd.Message, sd.Attributes, sd.Annotations , sd.ParentSpanID, sd.SpanID, sd.ChildSpanCount , ) }
  18. TextTraceExporter TestMainͱ͔Ͱৗʹग़͠·͢ exporter := NewTextTraceExporter( ) trace.RegisterExporter(exporter ) trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})

  19. ͓·͚ Spannerͷઃఆྫ spanner.ClientConfig { // ઀ଓͷઃఆΛߦ͏ // DUMP_TEST_TRACE Λ TRUE

    ʹͨ͠ͱ͖ɺBatchCreateSessions, BeginTransaction, DeleteSession ͱ͔ͷtrace͕ΊͪΌΊͪΌग़ΔͷͰ ਺Λগͳ͍ͨ͘͠ SessionPoolConfig: spanner.SessionPoolConfig { MinOpened: 2, // RWTx + ApplyAtLeastOnc e MaxOpened: 5 , MaxIdle: 0 , MaxBurst: 5 , WriteSessions: 0.5 , HealthCheckWorkers: 2 , HealthCheckInterval: 0 , TrackSessionHandles: true , } , },
  20. ༨ஊ ຊ೔ͷࡶஊͰ͢

  21. ݱঢ়ͷࠔΓ •spanner.CommitTimestam p •Txޙʹ஋ࠩ͠ସ͍͑ͨ(frontʹฦ͢ͷͰ

  22. ݱঢ়ͷࠔΓ •Schema managementͲ͏͠Α •wrench?

  23. ݱঢ়ͷࠔΓ •TextTraceExporterΑΓGUI͕΄͍͠ … •ݟΔͷ͕஍ຯʹΊΜͲ͏

  24. ࣗ࡞πʔϧ • sq b • Datastore likeͳॻ͖ຯͷDMLϏϧμ • si g

    • Goͷstruct͔ΒSQL૊Έཱͯ༻ͷίʔυΛੜ੒͢Δ • sid x • DDL͔ΒIndex৘ใΛ࣋ͭίʔυΛੜ੒͢Δ • cursor(Ծ ) • Datastore likeͳcursorੜ੒ϥΠϒϥϦ ݱঢ়ະެ։
  25. None