Merhaba arkadaşlar, uzun zamandır bir şeyler karalayamıyordum. Bugün sizlerle mongoose ile Express serverda nasıl birden fazla MongoDB sunucusuna bağlanabiliriz onu göstereceğim. Hatalarım, eksiklerim olabilir veya daha kolay uğraş gerektirmeyen bir çözümü var ise bilmek ve yazıma eklemek isterim. Lütfen yazının altına yorum olarak girin ki, okuyucuları yanlış yönlendirmeyelim.
Ne zaman ihtiyaç duyarım?
MongoDB sunucusuna epey bir yük bindiği için, bazı raporlama sorgularında artık yetersiz kalmaya başlamıştı. Aklımıza verilerin bir kısmını ana sunucudan bir kısmını replika sunucumuzdan çekmek geldi fakat sorgularımız tek bir MongoUrl üzerinden gidip geliyordu. Sorguların replika sunucumuza gitmesi için Express serverda birkaç değişiklik yapmamız gerekti. Bu tarz 2. bir sunucuya ihtiyaç duyduğunuz zamanlarda, aşağıda göstereceğim yöntemi kullanabilirsiniz.
Nasıl kullanabilirim?
Express serverda bildiğiniz gibi normal şartlarda server başlangıç dosyamızda aşağıdaki gibi MongoDB’ye bağlanabiliyoruz.
// import mongoose
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/dbname");
Farklı bir MongoDB sunucusuna daha bağlanmak için ise bir db_connect.js
dosyası oluşturalım. İsmi önemli değil, tamamen tercihinize bağlı. Bu dosyayı mongoose import ettiğimiz yerde, mongoose yerine kullanacağız.
// db_connect.js
var mongoose = require("mongoose");
// Create a connection for the primary MongoDB server
mongoose.primary_conn = mongoose.createConnection("mongodb://host1:27017/dbname");
mongoose.primary_conn.on("open", () => {
console.log("Connected correctly to the primary MongoDB server.");
});
mongoose.primary_conn.on("error", () => {
console.error.bind(console, "connection primary MongoDB error:");
});
// Create a connection for the secondary MongoDB server
mongoose.secondary_conn = mongoose.createConnection("mongodb://host2:27017/dbname");
mongoose.secondary_conn.on("open", () => {
console.log("Connected correctly to the secondary MongoDB server.");
});
mongoose.secondary_conn.on("error", () => {
console.error.bind(console, "connection secondary MongoDB error:");
});
module.exports = mongoose;
Gördüğünüz üzere 2 farklı bağlantı oluşturup mongooseu export ediyoruz. Fakat burada önemli bir nokta var. Eğer 2 farklı sunucudan model kullanarak veri çekecekseniz, yukarıda oluşturduğumuz primary veya secondary bağlantıyı kullanan farklı model dosyaları oluşturmalısınız.
Hemen bir örnek yapalım. Users ve Products adında 2 modeliniz olduğunu varsayıyorum. Users modeli primary bağlantıyı, Products modeli ise secondary bağlantıyı kullanacağını düşünelim. O halde, model dosyalarımızın içeriği şu şekilde olmalıdır;
// users model
var mongoose = require("./db_connect");
var userSchema = new Schema({
username: String,
firstname: String,
lastname: String,
createdAt: { type: Date, default: Date.now },
});
var Users = mongoose.primary_conn.model("users", userSchema);
module.exports = Users;
// products model içeriği
var mongoose = require("./db_connect");
var productSchema = new Schema({
name: String,
code: String,
createdAt: { type: Date, default: Date.now },
});
var Products = mongoose.secondary_conn.model("products", productSchema);
module.exports = Products;
Bu kadar basit, şu an verileri farklı sunuculardan çekebiliriz :)
Replika Konusunda Ufak Bir Not
Bu konuda benim karşılaştığım bir sorun şu oldu; Sorguları replika sunucuna gönderdiğim halde, otomatik olarak ana sunucuya gitti. Burada db_connect dosyasında replika sunucusuna giden Mongo URL’e 2 tane parametre eklemek gerekiyor.
- replicaSet=replName
Replikasyonu kurarken kullandığımız replika setin adını vermek gerekiyor. Fakat bunu vermek yetmiyor, hala primary olan node hangisi ise ona gidiyor. - readPreference=secondaryPreferred
Bu parametre bütün sihri gerçekleştiren kısım. Verileri getirirken öncelikle secondary olan node hangisi ise, ondan getir. Eğer okuyamazsan ise primary olan node üzerinden getir diyoruz.
Yani toparlarsak, eğer replika sunucunuzdan veri çekmek isterseniz temelde şöyle bir connection URL’e sahip olmanız gerekiyor.
mongodb://localhost:27017/dbName?replicaSet=replName&readPreference=secondaryPreferred
Umarım anlattıklarım faydalı olmuştur ve birilerine faydalı olur. Sağlıcakla kalın.