Je ne peux pas me débarrasser de l'habitude de produire des choses inutiles. Cette fois, j'ai écrit un article sur le code du compteur de lignes qui était inutilement multithread.
Certains fichiers sont plus rapides que wc -l, ce qui peut être utile pour ceux qui souhaitent compter les lignes le plus rapidement.
Go étudie seul. Nous attendons avec impatience vos suggestions concernant les erreurs et une meilleure rédaction.
"Traitement parallèle en langue Go" (Pourquoi ne l'avez-vous pas lu plus tôt?) Rubbing io.Reader (Parlez-moi de la cachette de Go?)
Compte le nombre de lignes dans le fichier spécifié par l'argument et l'affiche à l'écran.
Les valeurs suivantes peuvent être spécifiées dans l'argument -Nom de fichier (-f) -Nombre de divisions pour la lecture fractionnée (-s) -Nombre de threads pour le traitement parallèle (-t) -Taille du tampon de lecture (-b)
-Compte du nombre de lignes par traitement multi-thread en utilisant goroutine et canaux -Rubbing du fichier avec io.Reader (Rubbing io.Reader)
Le flux de traitement général est le suivant.
Le code complet est ici
Importez les bibliothèques requises. Utilisez flag pour recevoir des arguments et glog pour la journalisation.
package main
import (
"bytes"
"flag"
"fmt"
"io"
"math"
"os"
"sync"
"time"
"github.com/golang/glog"
)
Déclarez des variables en définissant une structure pour recevoir des arguments.
// Arg is struct for commandline arg.
type Arg struct {
//Dossier à traiter
targetFile string
//Nombre de divisions lors du comptage des divisions
splitNum int
//Threads s'exécutant simultanément(Maximum)nombre
maxThreads int
//Taille du tampon pour la lecture des fichiers
buffersize int
}
var (
arg Arg
)
Écrivez le processus d'expansion des arguments, etc.
Puisque glog prend son propre argument, nous utilisons flag pour redéfinir et initialiser le propre argument de glog. Lorsque la commande help est affichée, l'explication de l'argument de glog est également affichée et c'est déroutant, donc j'ai mis "(go-lc)" dans l'explication de l'argument de ce processus pour le distinguer (cette zone est plus intelligente) Il semble y avoir un moyen de l'écrire).
func init() {
//Définir le message d'aide
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "%s\n", fmt.Sprintf("%s -f TARGETFILE [options] [glog options]",
os.Args[0]))
flag.PrintDefaults()
}
//Réglage initial de l'enregistreur
_ = flag.Set("stderrthreshold", "INFO")
_ = flag.Set("v", "0")
//Définition des options de ligne de commande
flag.StringVar(&arg.targetFile, "f", "", "(go-lc) Target File.")
flag.IntVar(&arg.splitNum, "s", 2, "(go-lc) Num of File split.")
flag.IntVar(&arg.maxThreads, "t", 2, "(go-lc) Max Num of Threads.")
flag.IntVar(&arg.buffersize, "b", 1024*1024, "(go-lc) Size of ReadBuffer(default=1024*1024).")
}
L'aide à la commande dans cette configuration s'affiche comme suit: L'aide de glog est assez bruyante.
(C'est bruyant, mais c'est facile pour un petit outil car vous n'avez pas à implémenter vous-même le processus de changement de niveau de journal.)
> ./bin/go-lc --help
./bin/go-lc -f TARGETFILE [options] [glog options]
-alsologtostderr
log to standard error as well as files
-b int
(go-lc) Size of ReadBuffer (default 1048576)
-f string
(go-lc) Target File
-log_backtrace_at value
when logging hits line file:N, emit a stack trace
-log_dir string
If non-empty, write log files in this directory
-logtostderr
log to standard error instead of files
-s int
(go-lc) Num of File split (default 2)
-stderrthreshold value
logs at or above this threshold go to stderr
-t int
(go-lc) Max Num of Threads (default 2)
-v value
log level for V logs
-vmodule value
comma-separated list of pattern=N settings for file-filtered logging
Je vais d'abord expliquer le processus principal. Cependant, il appelle simplement la fonction getNumOfLines qui agrège, reçoit le résultat et l'affiche à l'écran.
func main() {
flag.Parse()
glog.V(1).Infof("Start")
//Démarrer la minuterie pour le calcul du temps de traitement
startTime := time.Now()
//Exécuter le traitement d'agrégation
numOfLines, _ := getNumOfLines(arg.targetFile, arg.splitNum, arg.maxThreads, arg.buffersize)
//Afficher le temps de traitement
glog.V(1).Infof("End(%s)", time.Since(startTime))
fmt.Printf("%d\n", numOfLines)
}
getFileSize()
Une fonction pour obtenir la taille du fichier. Voir les commentaires pour le traitement.
func getFileSize(filename string) (int, error) {
//Ouvrez le fichier cible
fh, err := os.OpenFile(filename, 0, 0)
if err != nil {
return 0, err
}
defer fh.Close()
//Obtenir des informations sur les fichiers
fileinfo, err := fh.Stat()
if err != nil {
return 0, err
}
//Obtient et retourne le nombre d'octets dans le fichier
return int(fileinfo.Size()), nil
}
getNumOfLines()
C'est getNumOfLines () que je lisais dans main. C'est une fonction un peu longue, donc je vais l'expliquer séparément.
La première partie calcule le nombre de lectures de tampon effectuées pour l'ensemble du fichier. La formule suivante.
*** Nombre de lectures = Taille du fichier / Taille du tampon (+1 si non divisible) ***
func getNumOfLines(filename string, splitNum int, maxThreads int, buffersize int) (int, error) {
//Obtenir la taille du fichier
fsize, err := getFileSize(filename)
if err != nil {
return 0, err
}
// loglevel =Affichage d'informations avec 1
glog.V(1).Infof("FileSize : %10d byte", fsize)
glog.V(1).Infof("Read buffer: %10d byte", buffersize)
glog.V(1).Infof("Max Threads: %d", maxThreads)
glog.V(1).Infof("Split Num : %d", splitNum)
//Calculez combien de fois il peut être lu en unités de taille de la mémoire tampon.
var readCountTotal int = int(math.Trunc(float64(fsize) / float64(buffersize)))
//S'il y a un reste, ajoutez 1 au nombre de lectures
if fsize-(readCountTotal*buffersize) > 0 {
readCountTotal++
}
Ensuite, nous allons configurer le multi-threading. Waitgroup peut ne pas être nécessaire si vous déterminez comment utiliser le canal, mais il est utilisé par souci de clarté.
//Initialiser le groupe d'attente de fin
wg := &sync.WaitGroup{}
//Canal pour limiter le nombre de courses simultanées de goroutine
jc := make(chan interface{}, maxThreads)
defer close(jc)
//Canal pour recevoir le résultat du nombre de lignes de chaque goroutine
counterCh := make(chan int, maxThreads)
//A partir de la fin de veille goroutine de chaque goroutine,
//Canal de renvoi des résultats agrégés au traitement principal
resultCh := make(chan int)
defer close(resultCh)
//Démarrer la goroutine pour recevoir les résultats
//La condition finale est proche(counterCh)
go func(counterCh <-chan int) {
cAll := 0
for c := range counterCh {
cAll += c
glog.V(2).Infof("[receiver] receive: %d\n", c)
}
resultCh <- cAll
}(counterCh)
Il s'agit d'une boucle qui démarre goroutine (countWorker) qui compte le nombre de lignes. byteOffset est la position de début de lecture. EachReadCount est le nombre de fois où le tampon a été lu, mais la méthode de calcul provient du site suivant. Diviser n entiers aussi uniformément que possible Certaines personnes sont intelligentes.
Un canal appelé jc permet de contrôler le nombre de démarrages simultanés. C'est une utilisation standard, mais je pense que l'URL suivante sera utile. Comment contrôler le nombre maximum de Goroutines Limiter le nombre de processus parallèles en fonction du nombre de processeurs en langage Go Au fait, les deux sites ci-dessus utilisent le type booléen et le type int, mais selon "Traitement parallèle par langage Go (O'Reilly)", "Une interface d'une capacité de 0 est bonne pour le canal pour contrôler le nombre de startups!" C'est.
//Comptage de lignes Position de départ pour passer à la goroutine(0 est#Pour une goroutine)
var byteOffset int64 = 0
//Boucle de comptage de lignes pour démarrer la goroutine
for i := 0; i < splitNum; i++ {
//Combien de fois lire le tampon dans countLinesInThread
eachReadCount := int(math.Trunc(float64(readCountTotal+i) / float64(splitNum)))
//Remplissez un tableau de numéros de démarrage de goroutine
jc <- true
//Augmenter le groupe d'attente de un
wg.Add(1)
//Ligne de départ comptage goroutine
go countWorker(filename, eachReadCount, byteOffset, buffersize, wg, jc, counterCh)
//Décalage de lecture avancé
byteOffset += int64(eachReadCount * buffersize)
}
wg.Wait()
close(counterCh)
return <-resultCh, nil
}
countWorker()
Ensuite, définissez countWorker (), qui est le corps principal de goroutine. En fait, je viens d'ouvrir le fichier donné par filename, décale la position de lecture avec f.Seek, puis lis getNumOfCharsOnIo. Je pense que la partie qui ouvre le même fichier plusieurs fois est un peu redondante, mais comme il existe un processus de recherche pour la lecture fractionnée, je le fais (est-ce que cela a du sens de se séparer ici? J'ai un sentiment, mais je m'en fiche Dans certains cas, il est important d'avoir les premières intentions sur le site de développement des adultes).
func countWorker(filename string, eachReadCount int, byteOffset int64, buffersize int,
wg *sync.WaitGroup, jc <-chan interface{}, counter chan<- int) {
var c int = 0
defer func() {
//Les fonctions anonymes peuvent accéder aux variables de portée externe, il n'y a donc pas de problème
counter <- c
wg.Done()
<-jc
}()
// loglevel=Affichage d'informations avec 2
glog.V(2).Infof("[countWorker] start (offset: %d, read size: %d)\n", byteOffset, eachReadCount*buffersize)
//Rouvrir le fichier cible
//Le curseur de lecture de Seek est perturbé lors de l'utilisation du gestionnaire de fichiers d'origine
f, err := os.OpenFile(filename, 0, 0)
if err != nil {
return
}
defer f.Close()
//Déplacer vers la position de début de lecture spécifiée
_, err = f.Seek(byteOffset, 0)
if err != nil {
return
}
//Vous pouvez également passer un bufio créé comme suit à getNumOfCharsOnIo
//Cette fois io.Étant donné que la taille des données lues à partir de Reader peut être modifiée, elle n'est pas utilisée car elle est considérée comme ayant peu de mérite.
// br := bufio.NewReaderSize(f, 1024*1024)
c, err = getNumOfCharsOnIo(f, buffersize, eachReadCount)
if err != nil {
panic(err)
}
}
getNumOfCharsOnIo()
Enfin, définissez getNumOfCharsOnIo (), qui compte en fait le nombre de lignes. Le processus est similaire au fameux article "io.Reader sukore", mais bytes.IndexByte () est ajouté à la partie qui compte les sauts de ligne. J'utilise. Je pense que c'est correct de considérer le mécanisme UTF-8, mais il peut être plus sûr d'utiliser Index Rune qui est commenté. Hmm. C'était la même chose par rapport au résultat de wc dans certains fichiers réels, mais il peut y avoir des cas où le résultat est différent.
// io.Lisez buffersize à partir de Reader et répétez le processus de comptage du nombre d'occurrences de répétition de targetStr.
func getNumOfCharsOnIo(r io.Reader, buffersize int, repeatCount int) (int, error) {
//Initialiser le tampon de lecture
buf := make([]byte, buffersize)
//Variable pour stocker le nombre de lignes
var c int = 0
//À partir de la position de départ, lisez la chaîne d'octets par buffersize et affectez-la à buf
for j := 0; j < repeatCount; j++ {
n, err := r.Read(buf)
//Si la taille de lecture est 0
if n == 0 {
return c, err
}
//Traitement en cas d'erreur de lecture
if err != nil {
return c, err
}
//Offset pour scanner le contenu du tampon
of := 0
//Traitement pour compter les sauts de ligne dans Buffer
for {
//La taille est spécifiée par n car buf est utilisé autour.
// index := bytes.IndexRune(buf[of:n], rune('\n'))
index := bytes.IndexByte(buf[of:n], '\n')
//Après cela, quittez la boucle sans saut de ligne
if index == -1 {
break
}
// (Des sauts de ligne)Incrémenter le compteur
c++
//Poste de découverte+Avancer le décalage à 1
of += index + 1
}
}
return c, nil
}
La plupart des explications ont été laissées aux commentaires intégrés, mais c'est tout pour le code.
Le tout est ici
Puisqu'il s'agit d'un programme qui prend des options, je vais brièvement vous montrer comment l'utiliser.
> ./bin/go-lc --help
./bin/go-lc -f TARGETFILE [options] [glog options]
-alsologtostderr
log to standard error as well as files
-b int
(go-lc) Size of ReadBuffer (default 1048576)
-f string
(go-lc) Target File
-log_backtrace_at value
when logging hits line file:N, emit a stack trace
-log_dir string
If non-empty, write log files in this directory
-logtostderr
log to standard error instead of files
-s int
(go-lc) Num of File split (default 2)
-stderrthreshold value
logs at or above this threshold go to stderr
-t int
(go-lc) Max Num of Threads (default 2)
-v value
log level for V logs
-vmodule value
comma-separated list of pattern=N settings for file-filtered logging
> ./bin/go-lc -f /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
1428
Par défaut, il est divisé en deux et exécuté en deux threads.
> ./bin/go-lc -f /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql -v 5
I1216 20:47:23.781456 12091 main.go:233] Start
I1216 20:47:23.781785 12091 main.go:79] FileSize : 1426087753 byte
I1216 20:47:23.781801 12091 main.go:80] Read buffer: 1048576 byte
I1216 20:47:23.781816 12091 main.go:81] Max Threads: 2
I1216 20:47:23.781826 12091 main.go:82] Split Num : 2
I1216 20:47:23.781871 12091 main.go:160] [countWorker] start (offset: 713031680, read size: 714080256)
I1216 20:47:23.781953 12091 main.go:160] [countWorker] start (offset: 0, read size: 713031680)
I1216 20:47:23.957093 12091 main.go:115] [receiver] receive: 699
I1216 20:47:23.969989 12091 main.go:115] [receiver] receive: 729
I1216 20:47:23.970048 12091 main.go:242] End(188.280638ms)
1428
Il traite un fichier d'environ 1,4 Go en 0,188 seconde.
> ./bin/go-lc -f /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql -v 5 -s 4 -t 4
I1216 20:51:51.827208 13285 main.go:233] Start
I1216 20:51:51.827519 13285 main.go:79] FileSize : 1426087753 byte
I1216 20:51:51.827534 13285 main.go:80] Read buffer: 1048576 byte
I1216 20:51:51.827553 13285 main.go:81] Max Threads: 4
I1216 20:51:51.827565 13285 main.go:82] Split Num : 4
I1216 20:51:51.827607 13285 main.go:160] [countWorker] start (offset: 1069547520, read size: 357564416)
I1216 20:51:51.827706 13285 main.go:160] [countWorker] start (offset: 713031680, read size: 356515840)
I1216 20:51:51.827646 13285 main.go:160] [countWorker] start (offset: 356515840, read size: 356515840)
I1216 20:51:51.827642 13285 main.go:160] [countWorker] start (offset: 0, read size: 356515840)
I1216 20:51:51.938578 13285 main.go:115] [receiver] receive: 343
I1216 20:51:51.939430 13285 main.go:115] [receiver] receive: 356
I1216 20:51:51.952839 13285 main.go:115] [receiver] receive: 386
I1216 20:51:51.956868 13285 main.go:115] [receiver] receive: 343
I1216 20:51:51.956899 13285 main.go:242] End(129.400448ms)
1428
Avec le fichier précédent, il est plus rapide à 0,129 seconde.
> ./bin/go-lc -f /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql -v 5 -s 4 -t 4 -
b 1024
I1216 20:53:02.522702 13459 main.go:233] Start
I1216 20:53:02.523194 13459 main.go:79] FileSize : 1426087753 byte
I1216 20:53:02.523217 13459 main.go:80] Read buffer: 1024 byte
I1216 20:53:02.523222 13459 main.go:81] Max Threads: 4
I1216 20:53:02.523229 13459 main.go:82] Split Num : 4
I1216 20:53:02.523275 13459 main.go:160] [countWorker] start (offset: 1069565952, read size: 356521984)
I1216 20:53:02.523351 13459 main.go:160] [countWorker] start (offset: 0, read size: 356521984)
I1216 20:53:02.523442 13459 main.go:160] [countWorker] start (offset: 356521984, read size: 356521984)
I1216 20:53:02.526218 13459 main.go:160] [countWorker] start (offset: 713043968, read size: 356521984)
I1216 20:53:03.146721 13459 main.go:115] [receiver] receive: 343
I1216 20:53:03.149466 13459 main.go:115] [receiver] receive: 386
I1216 20:53:03.186216 13459 main.go:115] [receiver] receive: 356
I1216 20:53:03.190404 13459 main.go:115] [receiver] receive: 343
I1216 20:53:03.190443 13459 main.go:242] End(667.278999ms)
1428
Il a été ralenti à 0,667 seconde en raison du tampon plus petit et de l'inefficacité.
En passant, je pense que certaines personnes s'inquiètent du résultat de l'écriture d'un traitement aussi inutile et de la rapidité avec laquelle il sera. En regardant l'exemple d'utilisation, le résultat de la taille de tampon 1048576 (1024 * 1024) de 4 divisions et 4 threads est bon.
Le résultat de la commande wc -l pour le même fichier est
time wc -l /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
(Première fois)
1428 /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
0.04user 0.26system 0:00.30elapsed 100%CPU (0avgtext+0avgdata 2104maxresident)k
0inputs+0outputs (0major+76minor)pagefaults 0swaps
(Deuxième fois)
time wc -l /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
1428 /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
0.03user 0.22system 0:00.26elapsed 99%CPU (0avgtext+0avgdata 2068maxresident)k
0inputs+0outputs (0major+75minor)pagefaults 0swaps
(Troisième fois)
1428 /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
0.03user 0.22system 0:00.26elapsed 99%CPU (0avgtext+0avgdata 2124maxresident)k
0inputs+0outputs (0major+75minor)pagefaults 0swaps
(4e)
1428 /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
0.04user 0.20system 0:00.25elapsed 99%CPU (0avgtext+0avgdata 2104maxresident)k
0inputs+0outputs (0major+78minor)pagefaults 0swaps
(5ème fois)
1428 /mnt/v01/resource/wikipedia/jawiki/20191001/extract/jawiki-20191001-categorylinks.sql
0.04user 0.23system 0:00.27elapsed 100%CPU (0avgtext+0avgdata 2068maxresident)k
0inputs+0outputs (0major+75minor)pagefaults 0swaps
moyenne: 0.268s
La moyenne de 5 fois était de 0,268 seconde.
L'environnement de la machine est entièrement Google Cloud Platform Compute Engine (n1-standard-4 (vCPU x 4, mémoire 15 Go)) et le fichier cible est un fichier sql Wikidump de 1,4 Go.
Cela a pris 0,129 seconde en 4 divisions, ce qui est mieux que la commande wc -l. Cela valait le gaspillage.
En fait, le résultat ci-dessus est probablement dû au cache de fichiers de GCE. Lorsque je l'ai essayé avec un autre fichier de 20 Go, cela a pris environ 3 minutes comme suit. Cette taille est également plus rapide que wc, mais il semble qu'elle puisse être plus rapide car elle traite 1,4 Go en 0,3 seconde. Par conséquent, des fichiers de plusieurs Go peuvent être mis en cache. En d'autres termes, il y a un risque qu'il y ait une différence d'efficacité avant et après la mise en cache. Et comme GCE a des disques montés sur le réseau, la vitesse dépend également des conditions du réseau. Veuillez consulter les résultats ci-dessus pour référence seulement.
Répertoriez les résultats de l'exécution de wc -l et de ce programme pour un fichier d'environ 20 Go.
> time wc -l /mnt/v01/resource/wikipedia/enwiki/20191001/extract/enwiki-20191001-categorylinks.sql
(wc 1ère fois)
19525 /mnt/v01/resource/wikipedia/enwiki/20191001/extract/enwiki-20191001-categorylinks.sql
0.91user 8.21system 3:58.40elapsed 3%CPU (0avgtext+0avgdata 2116maxresident)k
31893064inputs+0outputs (0major+75minor)pagefaults 0swaps
(wc deuxième fois)
19525 /mnt/v01/resource/wikipedia/enwiki/20191001/extract/enwiki-20191001-categorylinks.sql
0.86user 7.86system 3:09.32elapsed 4%CPU (0avgtext+0avgdata 2044maxresident)k
26220800inputs+0outputs (0major+77minor)pagefaults 0swaps
(go-lc 1ère fois)
bin/go-lc -f /mnt/v01/resource/wikipedia/enwiki/20191001/extract/enwiki-20191001-categorylinks.sql -v 5 -t 4 -s 4
I1216 21:19:05.381636 14202 main.go:233] Start
I1216 21:19:05.384584 14202 main.go:79] FileSize : 20234931295 byte
I1216 21:19:05.384601 14202 main.go:80] Read buffer: 1048576 byte
I1216 21:19:05.384605 14202 main.go:81] Max Threads: 4
I1216 21:19:05.384609 14202 main.go:82] Split Num : 4
I1216 21:19:05.384704 14202 main.go:160] [countWorker] start (offset: 15176040448, read size: 5059379200)
I1216 21:19:05.384733 14202 main.go:160] [countWorker] start (offset: 0, read size: 5058330624)
I1216 21:19:05.384786 14202 main.go:160] [countWorker] start (offset: 5058330624, read size: 5058330624)
I1216 21:19:05.384859 14202 main.go:160] [countWorker] start (offset: 10116661248, read size: 5059379200)
I1216 21:19:06.836037 14202 main.go:115] [receiver] receive: 4881
I1216 21:20:49.994339 14202 main.go:115] [receiver] receive: 4866
I1216 21:20:56.968630 14202 main.go:115] [receiver] receive: 4910
I1216 21:21:00.825423 14202 main.go:115] [receiver] receive: 4868
I1216 21:21:00.825466 14202 main.go:242] End(1m55.440902834s)
19525
(go-lc 2ème fois)
bin/go-lc -f /mnt/v01/resource/wikipedia/enwiki/20191001/extract/enwiki-20191001-categorylinks.sql -v 5 -t 4 -s 4
I1216 21:21:19.065087 14343 main.go:233] Start
I1216 21:21:19.066146 14343 main.go:79] FileSize : 20234931295 byte
I1216 21:21:19.066164 14343 main.go:80] Read buffer: 1048576 byte
I1216 21:21:19.066169 14343 main.go:81] Max Threads: 4
I1216 21:21:19.066182 14343 main.go:82] Split Num : 4
I1216 21:21:19.066232 14343 main.go:160] [countWorker] start (offset: 15176040448, read size: 5059379200)
I1216 21:21:19.066234 14343 main.go:160] [countWorker] start (offset: 0, read size: 5058330624)
I1216 21:21:19.066314 14343 main.go:160] [countWorker] start (offset: 5058330624, read size: 5058330624)
I1216 21:21:19.066377 14343 main.go:160] [countWorker] start (offset: 10116661248, read size: 5059379200)
I1216 21:21:20.477393 14343 main.go:115] [receiver] receive: 4881
I1216 21:23:04.790516 14343 main.go:115] [receiver] receive: 4910
I1216 21:23:35.783612 14343 main.go:115] [receiver] receive: 4868
I1216 21:23:53.859878 14343 main.go:115] [receiver] receive: 4866
I1216 21:23:53.859920 14343 main.go:242] End(2m34.793812658s)
19525
Ce processus a également été créé comme un test pour traiter un gros fichier texte comme Wikidump à grande vitesse sans charger le tout.
Depuis que j'ai obtenu le gestionnaire de lecture séparément, j'ai essayé de monter 4 disques sur GCE, de copier le même fichier et de lire avec la distribution de disque, mais je m'attendais à ce que la vitesse de communication avec le NAS soit limitée. L'effet n'a pas été obtenu (c'était presque la même vitesse que lors de la lecture séparée avec une unité). GCS, qui est un service de stockage de GCP, prend en charge la lecture en unités d'octets, ou il peut être plus rapide d'effectuer une lecture fractionnée pour GCS. Cette zone semble avoir l'avantage d'io.Reader, ou l'avantage de Go qui permet de réutiliser le code en lisant à partir d'un fichier et via l'API GCS.
Merci de rester avec nous jusqu'à la fin de l'article qui semble redévelopper les roues de manière compliquée.
Recommended Posts