1000 万のレコードを mongodb に挿入する簡単な例を作成しました。順番に機能させることから始めました。次に、並行処理の方法を調べたところ、ゴルーチンが見つかりました。これは私が望んでいるように思えますが、期待どおりに動作していません。すべてのゴルーチンが終了する前にプログラムが終了するのをブロックする WaitGroup を実装しましたが、まだ問題があります。
そこで、何が起こっているのかから始めて、コードを示します。ゴルーチンなしでコードを実行すると、1,000 万件のレコードすべてが mongodb に正常に挿入されます。ただし、ゴルーチンを追加すると、不確定な量が入力されます..一般的には約8500で、数百です。mongodb ログをチェックして、問題が発生していないかどうかを確認しましたが、何も表示されていません。だから、ログに記録されていないだけなのかどうかはわかりません。とにかく、ここにコードがあります:
(補足: 一度に 1 つのレコードを処理していますが、将来的に複数のレコードを一度にテストできるようにメソッドに分割しました。mongodb でそれを行う方法がわかりません。まだ。)
package main
import (
"fmt"
"labix.org/v2/mgo"
"strconv"
"time"
"sync"
)
// structs
type Reading struct {
Id string
Name string
}
var waitGroup sync.WaitGroup
// methods
func main() {
// Setup timer
startTime := time.Now()
// Setup collection
collection := getCollection("test", "readings")
fmt.Println("collection complete: " + strconv.FormatFloat(time.Since(startTime).Seconds(), 'f', 2, 64))
// Setup readings
readings := prepareReadings()
fmt.Println("readings prepared: " + strconv.FormatFloat(time.Since(startTime).Seconds(), 'f', 2, 64))
// Insert readings
for i := 1; i <= 1000000; i++ {
waitGroup.Add(1)
go insertReadings(collection, readings)
// fmt.Print(".")
if i % 1000 == 0 {
fmt.Println("1000 readings queued for insert: " + strconv.FormatFloat(time.Since(startTime).Seconds(), 'f', 2, 64))
}
}
waitGroup.Wait()
fmt.Println("all readings inserted: " + strconv.FormatFloat(time.Since(startTime).Seconds(), 'f', 2, 64))
}
func getCollection(databaseName string, tableName string) *mgo.Collection {
session, err := mgo.Dial("localhost")
if err != nil {
// panic(err)
fmt.Println("error getCollection:", err)
}
// defer session.Close()
// Optional. Switch the session to a monotonic behavior.
// session.SetMode(mgo.Monotonic, true)
collection := session.DB(databaseName).C(tableName)
return collection
}
func insertReadings(collection *mgo.Collection, readings []Reading) {
err := collection.Insert(readings)
if err != nil {
// panic(err)
fmt.Println("error insertReadings:", err)
}
waitGroup.Done()
}
func prepareReadings() []Reading {
var readings []Reading
for i := 1; i <= 1; i++ {
readings = append(readings, Reading{Name: "Thing"})
}
return readings
}