DEV Community

Cover image for Mongodb Veritabanınızı Google Cloud Storage'a Aktarın
Ali İlteriş Keskin
Ali İlteriş Keskin

Posted on

Mongodb Veritabanınızı Google Cloud Storage'a Aktarın

erhaba arkadaşlar, bu yazımda heybooster'ın
veritabanı yedeği için yazdığımız bir koddan bahsedeceğim. Bu kod veritabanımızı
Google Cloud Storageda
açtığımız bir bucketa yolluyor. Detayları aşağıda konuşalım :)


Neden Mongodb?

MongoDB

Bu yazı tek tek neyin ne olduğunu açıklayan bir yazı olmayacak ancak kısaca yazıda
geçen teknolojilerden bahsetmek istiyorum. Mongodb
birçok programlama diline destek veren, ölçeklenebilir açık kaynak kodlu bir
NoSQL veritabanıdır. Verileri SQL veritabanlarından farklı olarak JSON formatta
tutmaktadır. Bu da bizim istediğimiz bir özellik. Mongodb NoSQL yapısıyla
Heybooster'ın tüm ihtiyaçlarına çözüm sunuyordu. Bu yüzden veritabanı olarak
Mongodb'yi tercih ettik.


Neden Google Cloud Storage?

Google Cloud Storage

Yazının kalanında "Google Cloud Storage" yerine "GCS" yazacağım. Öncelikle ne olduğundan
bahsedelim. Wikipedia'a göre aşağıdaki gibi bir tanımı var. Bu tanım ne olduğunu
anlamaya yetecektir diye düşünüyorum.

Google Cloud Storage, Google Cloud Platform altyapısındaki verileri depolamak ve
bunlara erişmek için RESTful bir çevrimiçi dosya depolama web hizmetidir. Hizmet,
Google'ın bulutunun performansını ve ölçeklenebilirliğini gelişmiş güvenlik ve
paylaşım yetenekleriyle birleştirir


Peki Biz Ne İstiyorduk?

Who we are meme

Gelelim asıl konuya, biz ne istiyorduk? Bizim isteğimiz gün içinde oluşan veritabanındaki
bazı verileri yedeklemek. Yani günlük veritabanı yedeği diyebiliriz. Peki bunu nasıl yapacağız?
Mongodb database tool içinde bulunan mongodump programını kullanarak veritabanını export
edebileceğiz. Sonra? Sonrası için ilk planımız Digital Ocean'dan
bir ubuntu makine açıp orda yedeklemekti ancak GCS'a göre çok daha pahalıya geliyordu.
Bizim kararımız bu noktada netleşti.


Operasyon Başlasın 👊

Maskeli Beşler Irak

Kararlarımızı verdikten sonra gereklilikleri sağlayıp kod yazmaya başladık. Kodu
yazı sonunda paylaşacağım ama önce gerekliliklerden kısaca bahsedeyim. Verilerini
elde edeceğimiz veritabanının username, password gibi bilgilerine ihtiyacımız var.
Sonrasında GCS için credential işlemleri ve gerekli GCS kütüphanesini yüklememiz
gerekiyor. Bunları yaptıktan sonra kodumuzu yazabiliriz.

Gelelim koda.

import os
from dotenv import load_dotenv
from google.cloud import storage
from bson.objectid import ObjectId
from datetime import datetime
import time
from os import listdir
from os.path import isfile, join

load_dotenv()

DB_USER = os.environ['DB_USER']
DB_PASSWORD = os.environ['DB_PASSWORD']
DB_NAME = os.environ['DB_NAME']
BUCKET_NAME = os.environ['BUCKET_NAME']


def mongodump_reports(archive_file):
    today = datetime.today()
    date = datetime(today.year, today.month, today.day, 0, 0, 0)
    # Required for ignoring the documents older than 1 day
    idMin = ObjectId(format(int(date.timestamp()), 'x') + "0000000000000000")

    # Using --out options to fix the file name
    DB_DUMP_COMMAND = """
    mongodump --uri "mongodb://{}:{}@heybooster-shard-00-00-yue91.mongodb.net:27017,heybooster-shard-00-01-yue91.mongodb.net:27017,heybooster-shard-00-02-yue91.mongodb.net:27017/{}?authSource=admin&replicaSet=heybooster-shard-0&retryWrites=true&ssl=true&w=majority" --collection reports --out {} --query""".format(
        DB_USER, DB_PASSWORD, DB_NAME, archive_file) + """ '{"_id": {"$gte": ObjectId("'""" + str(idMin) + """'")}}'"""
    os.system(DB_DUMP_COMMAND)


def list_blobs(bucket_name):
    """Lists all the blobs in the bucket."""

    storage_client = storage.Client.from_service_account_json(
        'credentials.json')

    # Note: Client.list_blobs requires at least package version 1.17.0.
    return storage_client.list_blobs(bucket_name)


def upload_backup_file(bucket_name, archive_file, destination_blob):
    """Uploads a file to the bucket."""

    storage_client = storage.Client.from_service_account_json(
        'credentials.json')
    bucket = storage_client.bucket(bucket_name)

    current = os.getcwd()
    a = listdir(archive_file)[0]
    path = current + "/" + archive_file + "/" + a
    files = [f for f in listdir(path) if isfile(join(path, f))]
    for file in files:
        archive_file = path + '/' + file
        destination_blob = destination_blob + '_' + file
        blob = bucket.blob(destination_blob)
        blob.upload_from_filename(archive_file)

    print("File {} uploaded to {}.".format(archive_file, destination_blob))


def remove_old_reports(bucket_name, archive_file):
    """Deletes a blob from the bucket."""

    storage_client = storage.Client.from_service_account_json(
        'credentials.json')

    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(archive_file)
    blob.delete()

    print("Blob {} deleted.".format(archive_file))


def start():
    archive_file_name = "mongo_backup_" + time.strftime('%x').replace('/', '_')
    destination_blob_name = archive_file_name
    mongodump_reports(archive_file_name)
    upload_backup_file(BUCKET_NAME, archive_file_name, destination_blob_name)


if __name__ == '__main__':
    start()
Enter fullscreen mode Exit fullscreen mode

Kod karmaşık olmadığı için anlaşılır diye düşünüyorum. Kısaca bahsedeyim, veritabanımızı
export eden fonksiyon "mongodump_export"un yaptığı şey mongodump komutunu çalıştırmak. Başka
bir görevi yok. "list_blobs" isimli fonksiyon ise bucket içindeki dosyaları listelememizi
sağlıyor. "upload_backup_file" ise istediğimiz dosyanın bucketa yüklenmesini sağlıyor.
"remove_old_file" isminden anlaşıldığı gibi eski dosyaları silmemizi sağlıyor. Tabi bunu
dosya ismini parametre olarak alarak yapıyor.

Kodumuz bundan ibaret. Serverda bu kodun günlük olarak çalışmasını sağlamamız yeterli.
Anlamadığınız bir yer varsa sorabilirsiniz. Umarım işinize yaramıştır. İyi pazarlar dilerim :)

Top comments (3)

Collapse
 
demir profile image
Mehmet

Buralarda türkçe içerik görmek ne güzel. Emeklerinize sağlık.

Collapse
 
ilteriskeskin profile image
Ali İlteriş Keskin

Teşekkür ederim. Yarın ve ertesi gün de eski yazılarımı buraya ekleyeceğim. Sonrasında da yeni yazılarımı burda yazacağım :)

Collapse
 
demir profile image
Mehmet

Ne güzel. Yolunuz açık olsun..