mongodb, replikasi dan kesalahan: {"$ err": "not master and slaveOk = false", "code": 13435}

174

Saya mencoba set replika mongo untuk pertama kalinya.

Saya menggunakan ubuntu di ec2 dan saya mem-boot tiga instance. Saya menggunakan alamat IP pribadi masing-masing contoh. Saya memilih sebagai yang utama dan di bawah ini adalah kode.

mongo --host Private IP Address
rs.initiate()
rs.add(“Private IP Address”)
rs.addArb(“Private IP Address”)

Semua pada titik ini baik-baik saja. Ketika saya pergi ke situs http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:8017/_replSet saya melihat bahwa saya memiliki primary, seconday, dan arbitor.

Ok, sekarang untuk tes.

Pada dasarnya membuat database dalam hal ini adalah kode:

use tt
db.tt.save( { a : 123 } )

di sekunder, saya kemudian melakukan ini dan mendapatkan kesalahan di bawah ini:

db.tt.find()
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }

Saya sangat baru untuk mongodb dan meniru tetapi saya berpikir bahwa jika saya melakukan sesuatu dalam satu, itu pergi ke yang lain. Jadi, jika saya menambahkan catatan dalam satu, apa yang harus saya lakukan untuk mereplikasi seluruh mesin?

eLRuLL
sumber
tahu bahwa saya harus menggunakan rs.slaveOk (); Itu membuat saya pertanyaan lain. Saya harus melakukan ini, lakukan ini untuk setiap permintaan? Bagaimana jika saya berada di node master?

Jawaban:

282

Anda harus mengatur mode "budak oke" untuk membiarkan shell mongo tahu bahwa Anda mengizinkan membaca dari sekunder. Ini untuk melindungi Anda dan aplikasi Anda dari melakukan pembacaan yang konsisten pada akhirnya secara tidak sengaja. Anda dapat melakukan ini di shell dengan:

rs.slaveOk()

Setelah itu Anda dapat meminta secara normal dari sekunder.

Catatan tentang "konsistensi akhirnya": dalam keadaan normal, replika yang ditetapkan sekunder memiliki semua data yang sama dengan primer dalam satu detik atau kurang. Di bawah beban yang sangat tinggi, data yang telah Anda tulis ke utama mungkin perlu beberapa saat untuk direplikasi ke sekunder. Ini dikenal sebagai "replika lag", dan pembacaan dari lagging sekunder dikenal sebagai pembacaan "akhirnya konsisten", karena, sementara data yang baru ditulis akan muncul di beberapa titik (mencegah kegagalan jaringan, dll), mungkin tidak segera tersedia.

Sunting: Anda hanya perlu mengatur slaveok ketika meminta dari sekunder, dan hanya sekali per sesi.

dcrosta
sumber
3
Selalu periksa manual sebelum Anda menjalankan perintah yang tidak Anda mengerti pada DB Anda. Mungkin ada konsekuensi pada perintah yang jawabannya tidak dijelaskan. Apakah perintah ini mengubah cara membaca ope ration didistribusikan untuk semua koneksi ke set replika? Lebih baik cari tahu. Perintah ini muncul sejauh v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOk Anda dapat (dan harus) selalu mengganti bagian "/ manual /" dari URL docs.mongodb.com ke versi spesifik Anda untuk memastikan Anda mendapatkan info yang relevan.
Bruno Bronosky
45

Untuk menghindari mengetik rs.slaveOk()setiap saat, lakukan ini:

Buat file bernama replStart.js, mengandung satu baris:rs.slaveOk()

Kemudian sertakan --shell replStart.jsketika Anda meluncurkan shell Mongo. Tentu saja, jika Anda terhubung secara lokal ke satu instance, ini tidak menyimpan pengetikan apa pun.

Ed Norris
sumber
26
Cara yang lebih baik untuk menghemat pengetikan adalah dengan menambahkan rs.slaveOk()ke ~/.mongorc.jsfile Anda , yang akan secara otomatis dieksekusi ketika memulai mongo shell.
Stennie
2
Saya merasa berguna untuk meletakkan konfigurasi default ~/.mongorc.jsdan konfigurasi khusus di replStart.jsatau adminStart.jsatau apa pun.
Ed Norris
41

di mongodb2.0

Anda harus mengetik

rs.slaveOk()

di simpul mongod sekunder

andyshi
sumber
11

INI HANYA CATATAN UNTUK SIAPAPUN YANG MENGHADAPI MASALAH INI MENGGUNAKAN DRIVER RUBY

Saya memiliki masalah yang sama saat menggunakan Ruby Gem.

Untuk mengatur slaveOk di Ruby, Anda hanya meneruskannya sebagai argumen ketika Anda membuat klien seperti ini:

mongo_client = MongoClient.new("localhost", 27017, { slave_ok: true })

https://github.com/mongodb/mongo-ruby-driver/wiki/Tutorial#making-a-connection

mongo_client = MongoClient.new # (optional host/port args)

Perhatikan bahwa 'argumen' adalah argumen opsional ketiga.

campeterson
sumber
1

Saya hanya menambahkan jawaban ini untuk situasi yang canggung dari penyedia DB.

apa yang terjadi dalam kasus kami adalah db primer dan sekunder bergeser terbalik (primer ke sekunder dan sebaliknya) dan kami mendapatkan kesalahan yang sama.

jadi silakan periksa di pengaturan konfigurasi untuk status database yang dapat membantu Anda.

jit
sumber
0

Aku sampai di sini mencari kesalahan yang sama, tetapi dari Node.js driver asli . Jawaban bagi saya adalah kombinasi jawaban oleh campeterson dan Prabhat .

Masalahnya adalah readPreferencepengaturan default untuk primary, yang kemudian entah bagaimana mengarah ke slaveOkkesalahan yang membingungkan . Masalah saya adalah bahwa saya hanya ingin membaca dari set replika saya dari sembarang simpul. Saya bahkan tidak terhubung ke replaset. Saya hanya terhubung ke sembarang simpul untuk membacanya.

Pengaturan readPreferenceuntuk primaryPreferred(atau lebih baik ke ReadPreference.PRIMARY_PREFERREDkonstanta) menyelesaikannya untuk saya. Cukup berikan sebagai opsi ke MongoClient.connect()atau ke client.db()atau ke apa saja find(), aggregate()atau fungsi lainnya.

const { MongoClient, ReadPreference } = require('mongodb');
const client = await MongoClient.connect(MONGODB_CONNECTIONSTRING, { readPreference: ReadPreference.PRIMARY_PREFERRED });
kub1x
sumber