Cloudera Operational Database (COD) adalah solusi dbPaaS terkelola yang tersedia sebagai pengalaman di Cloudera Data Platform (CDP). Ini menawarkan akses klien multi-modal dengan nilai kunci NoSQL menggunakan API Apache HBase dan SQL relasional dengan JDBC (melalui Apache Phoenix). Yang terakhir membuat COD dapat diakses oleh pengembang yang terbiasa membangun aplikasi yang menggunakan MySQL, Postgres, dll. Manfaat utama COD meliputi:
- Penskalaan otomatis – berdasarkan penggunaan beban kerja cluster dan akan segera memiliki kemampuan untuk meningkatkan/menurunkan skala cluster
- Setel otomatis – kinerja yang lebih baik dalam jejak infrastruktur yang ada.
- Sembuhkan otomatis – selesaikan masalah operasional secara otomatis (segera hadir).
Di blog ini, saya akan mendemonstrasikan bagaimana COD dapat dengan mudah digunakan sebagai sistem backend untuk menyimpan data dan gambar untuk aplikasi web sederhana. Untuk membangun aplikasi ini, kita akan menggunakan Phoenix, salah satu komponen dasar COD, bersama dengan Flask. Untuk menyimpan gambar, kami akan menggunakan kemampuan HBase (penyimpanan backend Apache Phoenix) yang disebut MOB (objek sedang). MOB memungkinkan kita untuk membaca/menulis nilai dari 100k-10MB dengan cepat.
*Untuk kemudahan penggunaan pengembangan, Anda juga dapat menggunakan server kueri Phoenix alih-alih COD. Server kueri adalah build kecil phoenix yang dimaksudkan untuk tujuan pengembangan saja, dan data dihapus di setiap build.
Semua kode ada di repo github saya.
Petunjuk:
1. Masuk ke Cloudera Management Console dan pilih pengalaman Database Operasional
2. Pilih lingkungan Anda dan beri nama DB Anda
3. Setelah DB habis, ambil URL dari thin JDBC client
4. Setel kata sandi beban kerja CDP Anda
5. Proyek kloning git repo dan persyaratan pemasangan:$ pip install -r requirements.txt
6. Buka folder aplikasi dan jalankan “setup.py” – ini akan membuat tabel dengan 3 record pengguna dan gambar mereka $ python setup.py
7. Jalankan server web flask untuk memulai aplikasi web:$ FLASK_APP=app.py python -m flask run –port=8888 –host=127.0.0.1 –reload –with-threads –debugger
8. Buka http://localhost:8888/users di browser Anda. Anda harus dapat melihat aplikasi berjalan! Sesederhana itu.
Menelusuri Kode
1. Kelas Skema, Pada dasarnya menyimpan detail koneksi serta membuat dan melepaskan metode tabel. Seperti yang Anda lihat, kolom "foto" adalah jenis VARBINARY, yang diterjemahkan ke objek MOB di HBase:
import phoenixdb import phoenixdb.cursor class Schema: def __init__(self): opts = {} opts['authentication'] = 'BASIC' opts['avatica_user'] = '<cod workload username>' opts['avatica_password'] = '<cod workload pw>' database_url = "<cod thin jdbc url>" self.TABLENAME = "users" self.conn = phoenixdb.connect(database_url, autocommit=True,**opts) self.curs = self.conn.cursor() def create_users_table(self): query = """ CREATE TABLE IF NOT EXISTS """+self.TABLENAME+""" ( username VARCHAR NOT NULL, firstname VARCHAR, lastname VARCHAR, telephone VARCHAR, message VARCHAR, email VARCHAR, photo VARBINARY, photo_name VARCHAR, photo_type VARCHAR, photo_chars VARCHAR CONSTRAINT my_pk PRIMARY KEY (username)) """ self.curs.execute(query) def drop_users_table(self): query = "DROP TABLE "+self.TABLENAME self.curs.execute(query)
2 Kelas pengguna bertanggung jawab atas semua operasi aplikasi dengan Phoenix. Kami dapat memperbarui/menyisipkan (memasukkan dalam bahasa phoenix), menghapus, membuat daftar, dan menangani transaksi gambar:
import phoenixdb from schema import Schema import json class UsersModel: TABLENAME = "users" def __init__(self): db = Schema() self.conn=db.conn self.curs=db.curs def upsert(self, params): sql = "upsert into " + self.TABLENAME + \ " (username ,message,telephone,firstname,lastname,email) \ values (?,?,?,?,?,?)" data = (params.get('username'),params.get('message'),\ params.get('telephone'),params.get('firstname'),\ params.get('lastname'),params.get('email')) results = self.curs.execute(sql,data) return results def upsert_photo(self, params): if params.get('photo') is None: photo = bytes('','utf-8') else: photo = params.get('photo') sql = "upsert into " + self.TABLENAME + \ " (username, photo,photo_name) values (?,?,?)" data = (params.get('username'),photo, params.get('photo_name')) results = self.curs.execute(sql,data) return results def delete(self, username): query = f"DELETE from {self.TABLENAME} " \ f"WHERE username = {username}" self.curs.execute(query) def list_items(self, where_clause="",format="json"): query = f"SELECT username ,email,message,telephone,firstname,\ lastname,photo_name " \ f"from {self.TABLENAME} WHERE " + where_clause self.curs.execute(query) if format=="json": r = [dict((self.curs.description[i][0].lower(), value) \ for i, value in enumerate(row)) for row in \ self.curs.fetchall()] self.conn.close() data={'data': r } return json.dumps(data) result_set=self.curs.fetchall() result = [{column: row[i] for i, column in enumerate(result_set[0].keys())} for row in result_set] return result def get_image(self, username): query = f"SELECT photo,photo_name " \ f"from {self.TABLENAME} WHERE username='"+username+"'" self.curs.execute(query) row = self.curs.fetchone() return row
3. App.py adalah router utama untuk aplikasi. Ini berisi semua penanganan dengan input pengguna dan mengarahkannya ke metode koneksi. Saya memisahkan penanganan gambar untuk kemudahan penggunaan, dan dengan cara itu saya bisa mendapatkan gambar tertentu untuk pengguna:
from flask import Flask, request, send_file ,jsonify,render_template import phoenixdb import io from users import UsersModel from schema import Schema import json app = Flask(__name__) @app.after_request def add_headers(response): response.headers['Access-Control-Allow-Origin'] = '*' response.headers['Access-Control-Allow-Headers'] = \ "Content-Type, Access-Control-Allow-Headers, Authorization, \ X-Requested-With" response.headers['Access-Control-Allow-Methods']= "POST, GET, PUT, \ DELETE, OPTIONS" response.headers['Allow']= "POST, GET, PUT, OPTIONS" return response @app.route("/") def hello(): return "Hello World!" @app.route("/users") def return_form(): return render_template("users.html") @app.route("/handle_data",methods=['POST']) def handle_data(): if request.method == 'POST': username = request.form['username'] firstname = request.form['firstname'] lastname = request.form['lastname'] email = request.form['email'] telephone = request.form['telephone'] message = request.form['message'] photo = request.files['photo'] photo_bytes = photo.read() model=Schema() usersmodel=UsersModel() data = {'username':f"{username}",'firstname':f"{firstname}",\ 'lastname':f"{lastname}",'telephone':f"{telephone}",\ 'message':f"{message}"} photo_data = {'username':f"{username}",\ 'photo':photo_bytes,\ 'photo_name':f"{photo.filename}"} usersmodel.upsert(data) usersmodel.upsert_photo(photo_data) return render_template('users.html') else: return render_template('users.html') @app.route("/get_users",methods=['GET']) def get_users(): if request.method == 'GET': usersmodel=UsersModel() users = usersmodel.list_items("1=1") return users @app.route("/get_image",methods=['GET']) def get_image(): if request.method == 'GET': username = request.args.get('username') usersmodel=UsersModel() imagedb = usersmodel.get_image(username) return send_file(io.BytesIO(imagedb[0]),mimetype='image/png', \ attachment_filename=imagedb[1]) if __name__ == "__main__": Schema() app.run(debug=True, port=8888)
Langkah selanjutnya, Anda dapat menggunakan repo github ini untuk menguji aplikasi Anda.
Semoga bermanfaat, Selamat coding!!