Carregamento em massa de documentos em Couchbase
Esta postagem de blog é um exemplo de como carregar dados como JSON no Couchbase. Para os fins desta postagem, os dados extraídos do RDBMS como CSV serão convertidos em JSON. Os DBAs e administradores de RDBMS familiarizados com Oracle, SQL Server, MySQL etc. provavelmente estão procurando uma maneira de experimentar e testar o NoSQL. Geralmente, a primeira etapa do uso do NoSQL é converter tudo o que você tem em JSON.
O Couchbase oferece suporte a dados JSON e binários, mas, para os fins desta postagem, estamos analisando o tipo de dados mais rico, o JSON. É importante entender isso porque, ao carregar documentos no Couchbase em um formato diferente do JSON, os dados serão carregados como binários e poderão afetar a flexibilidade da visualização ao tentar criar visualizações ou índices. Com isso, vamos prosseguir com o carregamento de alguns documentos. Há duas maneiras de fazer isso, mas, para fins desta postagem, presumo que qualquer documento que você queira carregar já esteja no formato JSON e esteja compactado ou descompactado. A próxima seção descreverá um caminho possível para garantir que você esteja carregando dados JSON.
Alguns parceiros de ETL do Couchbase, como TalendO Talend oferece um conector para o Couchbase se você quiser uma GUI, talvez não queira lidar com arquivos CSV ou queira reordenar seus dados antes de enviá-los para o CSV ou apenas tenha a necessidade de ETL de dados de várias fontes antes de armazená-los no Couchbase Server. O Talend pode mapear e armazenar documentos diretamente como arquivos JSON antes de carregá-los no Couchbase, se desejado.
Este guia pressupõe que você tenha alguma familiaridade com Linux ou Mac, gerenciadores de pacotes e Ruby.
Para obter informações adicionais sobre a configuração do SDK, acesse: www.couchbase.com/developers/
As etapas usadas para preparar e carregar os dados são as seguintes:
- Preparar os dados: Dê uma olhada em alguns exemplos de ferramentas para converter o CSV em JSON.
- Carregar os dados: Examine alguns métodos para carregar os dados no couchbase por meio de scripts Ruby.
Pré-requisitos para Linux e Mac: Requer um ambiente de construção funcional!
- Libcouchbase: Como esse script usa Ruby, você deve ter a libcouchbase instalada antes de instalar a gem couchbase
- rubygem: certifique-se de que você tenha rubygems disponível para instalar o wrapper ruby do couchbase
- As gemas que usei são
- 'ruby-progressbar'
- 'couchbase'
- 'yaji'
- 'optparse'
- As gemas que usei são
- Analisador Yajl: também deve ser instalado como um pré-requisito para o YAJI.
- Instalar o Couchbase Gem: gem install couchbase
Se a configuração tiver sido bem-sucedida, os scripts em rubi que forneci deverão ser executados. Talvez seja necessário passar -h para o carregador de fluxo e garantir que você receba a mensagem de sintaxe. Por fim, não se esqueça de instalar também os GEMs listados, Yaji, optparse, couchbase e ruby-progressbar. Os links são fornecidos no final desta postagem.
Preparar os dados
Método 1 de preparação de dados: simples, rápido e consistente: csvtojson Script NodeJS
- Pode ser encontrado no Google e há outros também.
- Instalação via NPM, como
npm install -g csvtojson
Aqui está um exemplo de conversão para referência:
|
1 2 3 4 5 6 7 |
Austins-MBP:complaintstemp austin$ npm info csvtojson { name: 'csvtojson', description: 'A tool concentrating on converting csv data to JSON with customised parser supporting', 'dist-tags': { latest: '0.3.21' }, Austins-MBP:complaintstemp austin$ which csvtojson /usr/local/bin/csvtojson Austins-MBP:complaintstemp austin$ csvtojson data.gov_Consumer_Complaints.csv |
Método 2 de preparação de dados: escrever um script Ruby: csv2json.rb
O tempo para concluir o processo varia porque o Ruby é de thread único.
Uma observação adicional para esse script é que estou usando o YAJL em vez do módulo JSON padrão, que não lida com dados de streaming no Couchbase.
O script abaixo mostra a única alteração necessária. Isso melhorará o uso da memória durante a conversão. Se você não tiver instalado o YAJL antes, basta fazer isso: 'gem install yajl-ruby'
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/usr/bin/env ruby require 'rubygems' require 'csv' require 'pathname' #require 'JSON' require 'yajl/json_gem' Dir["./**/*.csv"].each do |csv_file_path| puts csv_file_path file_name = Pathname.new(csv_file_path).basename(".csv").to_s File.open("#{file_name}.json",'w') do |json_file| jsonData = CSV.read(csv_file_path, :headers => true, :header_converters => :symbol).map{|csv_row| csv_row.to_hash} json_file.write(JSON.pretty_generate(jsonData)); end end |
Etapas pós-conversão
Após a conclusão da conversão, é hora de compactar o arquivo com o ZIP:
|
1 2 3 4 5 |
Austins-MBP:complaintstemp austin$ ls Consumer_Complaints.csv Consumer_Complaints.json csv2json.rb Austins-MBP:complaintstemp austin$ zip Consumer_Complaints.zip Consumer_Complaints.json adding: Consumer_Complaints.json (deflated 95%) |
Coloque o(s) arquivo(s) zip em um diretório. Eu usei ~/Downloads/json_files/ em meu diretório pessoal.
|
1 |
Austins-MBP:complaintstemp austin$ cp Consumer_Complaints.zip ~/Downloads/json_files/ |
Depois que os dados tiverem sido preparados, você estará pronto para iniciar o carregamento. Os exemplos a seguir abordarão algumas maneiras comuns de colocar seus dados no Couchbase em massa.
A instalação do Couchbase vem com uma ferramenta integrada chamada carregador de documentos cbc. Ele pega arquivos de documentos individuais, com até 20 MB de tamanho, compactados ou dentro de um diretório e os carrega. No momento em que este artigo foi escrito carregador de documentos cbc requer vários arquivos no formato JSON contidos em um diretório. Em segundo lugar, discutirei uma ferramenta que escrevi em Ruby e que emprega a ferramenta YAJI Ruby Gem. O código referenciado é de uso gratuito e pode ser reescrito em qualquer linguagem que você se sinta confortável em usar.
Método 1 de carregamento de documentos: usando carregador de documentos cbc
O uso de um conjunto de arquivos individuais em um diretório é um caso de uso comum, mas depende da estrutura dos arquivos e diretórios a serem importados para refletir os documentos de desejo como eles aparecerão depois de carregados. Para ajudar a preservar essa estrutura, recomendamos empacotar os arquivos e diretórios a serem carregados em um arquivo .zip.
Os nomes das chaves de identificação dos documentos serão baseados nos arquivos de documentos fornecidos.
Observação: tEsse método não é ideal para grandes arquivos de documentos consolidados. Para arquivos grandes e monolíticos, exemplificarei como eles são carregados no Método 2, abaixo.
Em seguida, carregue o arquivo ou arquivos com o seguinte comando:
|
1 2 3 |
cbdocloader -u Administrator -p s3kre7Pa55 -b MyBucketToLoad -n 127.0.0.1:8091 -s 1000 ~/json_files/beer-sample.zip |
Observação:
O '-s 1000' é o tamanho da memória do bucket. Você precisará ajustar esse valor para o seu bucket.
Além disso, o bucket não precisa existir como carregador de documentos cbc o criará, mas esteja ciente da utilização de seus recursos antes de definir o sinalizador '-s' para garantir que você tenha RAM disponível.
Se tudo tiver sido bem-sucedido, você verá uma saída informando se os documentos foram carregados, quantos bytes, etc.
|
1 2 3 4 5 |
bucket: 2014-10-02-ny-json.zip, msgs transferred... : total | last | per sec byte : 242446488 | 242446488 | 3115728.2 |
Aqui está um breve script para carregar vários arquivos .zip em um determinado diretório:
|
1 2 3 4 5 6 7 8 |
#!/bin/bash JSON_Dir=~/json_files/ for ZipFile in $JSON_Dir/*.zip ; do /Applications/Couchbase Server.app/Contents/Resources/couchbase-core/bin/cbdocloader -u Administrator -p s3kre7Pa55 -b MyBucketToLoad -n 127.0.0.1:8091 -s 1000 $ZipFile done |
Método 2 de carregamento de documentos: streamloadjson
O outro método é carregar todos os documentos, separados por vírgula, de um único arquivo monolítico.
Para realizar esse método, preparei um script pequeno, mas eficaz, que usa o analisador de fluxo YAJI JSON e o chamei de streamjsonload.
As opções para esse programa são:
|
1 2 3 4 5 6 7 8 |
~$ ruby streamloadjson.rb -h ruby json loader -f, --jsonfile jsonfile JSON formatted filename -b, --bucketname BUCKETNAME bucket name -n, --hostname hostname hostname/ip address -r, --root JSONroot JSON root to parse -d, --docid SearchKey JSON Key ID -h, --help This menu |
Para carregar documentos com um arquivo JSON de teste, como fathers.json.txt, a partir de baixo, ele pode ser chamado da seguinte forma:
|
1 |
ruby streamloadjson.rb -b TestBucket -f fathers.json -n localhost -d id -r /fathers/ |
O script deve fornecer um resultado como o abaixo:
|
1 2 3 4 |
Reading from fathers.json JSON path processed is /fathers/ Couchbase node is localhost 29999 Time: 00:00:07 |>>---=---=---=---=---| Doc Loading |
Uma grande vantagem de usar o analisador YAJI é que ele requer um consumo muito baixo de memória. Isso significa que você poderia paginar os dados de entrada e dividi-los em vários fluxos para carregar no couchbase. Ele gerará processos discretos, já que o Ruby é de thread único, mas outra linguagem também poderia ser usada para multi-threading. Um exemplo disso está no repositório Github do Couchbase Labs.
Alguns aspectos a serem observados, Essa ferramenta carrega apenas arquivos de documentos monolíticos, tentará criar um ID automaticamente se não for fornecido com '-d' e exigirá algum ajuste fino da "raiz" com -r se nenhum documento for carregado.
O código mais recente do carregador está disponível em meu site repositório do githubmas também o forneci em linha abaixo:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
#!/usr/bin/env ruby #An example JSON file for testing is at: # https://github.com/ysharplanguage/FastJsonParser/raw/master/JsonTest/TestData/fathers.json.txt require 'ruby-progressbar' require 'rubygems' require 'couchbase' require 'yaji' require 'optparse' options = {} optparse = OptionParser.new do |opts| opts.banner = 'ruby json loader' opts.on('-f', '--jsonfile jsonfile', 'JSON formatted filename') do |jsonfile| options[:jsonfile] = jsonfile end opts.on('-b', '--bucketname BUCKETNAME', 'bucket name') do |bucketname| options[:bucketname] = bucketname end opts.on('-n', '--hostname hostname', 'hostname/ip address') do |hostname| options[:hostname] = hostname end opts.on('-r', '--root JSONroot', 'JSON root to parse') do |root| options[:root] = root end opts.on('-d', '--docid SearchKey', 'JSON Key ID') do |docid| options[:docid] = docid end opts.on('-h', '--help', 'This menu') { puts opts; exit} end optparse.parse! json_file = options[:jsonfile] bucket = options[:bucketname] host = options[:hostname] root = options[:root] docid = options[:docid] #set some defaults if not passed unless host host=localhost end unless root root="/" end puts "Reading from #{json_file}" puts "JSON path processed is #{root}" puts "Couchbase node is #{host}" # Connect to couchbase host and bucket provided on the command line client = Couchbase.connect(:bucket => bucket, :host => host) #Create the progressbar progressbar=ProgressBar.create(:title => "Doc Loading", :starting_at => 0, :total => nil, :throttle_rate => 0.01, :format => '%a |%b>>%i| %p%% %t', :length => 50) parser = YAJI::Parser.new(File.open(json_file)) parser.each(root.to_s).with_index do |doc,i| unless docid hashinfo=doc.hash.abs prikey="Doc_#{i}:#{hashinfo}" end prikey="#{docid}:#{doc["#{docid}"]}" client.set("#{prikey}", doc) print("rProcessed #{i} Documents") progressbar.increment end progressbar.finished? puts |
Finalização do trabalho
Depois que os dados tiverem sido carregados, faça login no console do Couchbase e comece a trabalhar com exibições de desenvolvimento para consultas e indexação.
Se estiver usando Couchbase Server 4.0 com N1QL você desejará criar um índice primário para poder explorar a interface semelhante ao SQL do Couchbase imediatamente e começar a aproveitar o poder da consulta N1QL por meio de nossos SDKs!
Muito obrigado às grandes pessoas da comunidade de código aberto por fornecerem a gem YAJL e a Sergey Avseyev pelo analisador YAJI. Sergey é um recurso do Couchbase muito experiente, responsável pelo trabalho do Ruby SDK, e eu também gostaria de incentivar qualquer um de vocês a experimentar nosso JRuby SDK e fornecer feedback.
Links:
Exemplos de CB Github - https://github.com/agonyou/cb-examples/
Analisador de fluxo YAJI - https://github.com/avsej/yaji
Gem YAJL JSON - https://github.com/brianmario/yajl-ruby
csv2json Gem - https://rubygems.org/gems/csv2json/
Couchbase Server 4 com N1QL - https://www.couchbase.com/nosql-databases/downloads
Se eu executar \'./cbdocloader -u tito -p foobar -b test -n 192.168.1.4:8091 -s 1000 /Users/tito/Desktop/sample.zip \' e o arquivo de amostra contém uma matriz JSON com apenas dois documentos, todo o conteúdo do arquivo é importado como um documento. Em outras palavras, o cbdocloader parece não perceber que o documento é uma matriz de objetos JSON. Além disso, o editor mostra \'Warning: JSON não deve ser uma matriz\'. Como o cbdocloader deve funcionar? Obrigado.
A propósito, se eu usar o exemplo de JSON encontrado em \'https://www.rubydoc.info/gems/c..., tenho o mesmo problema. Em ambos os casos, o conteúdo do arquivo é JSON válido. Parece que o cbdocloader não está cooperando :-/
Bem montado, você também pode usar https://sqlify.io/convert/csv/to/json para converter em JSON e, em seguida, carregar os documentos normalmente, em vez de desenvolver seu próprio script.