HBase
 sql >> Teknologi Basis Data >  >> NoSQL >> HBase

Di dalam Arsitektur Penyerapan Data Hampir Real-Time Santander (Bagian 2)

Terima kasih kepada Pedro Boado dan Abel Fernandez Alfonso dari tim teknik Santander atas kolaborasi mereka pada postingan ini tentang bagaimana Santander UK menggunakan Apache HBase sebagai mesin penyajian yang hampir real-time untuk mendukung aplikasi Spendlytics yang inovatif.

Aplikasi iOS Spendlytics dirancang untuk membantu pelanggan kartu kredit dan debit pribadi Santander mempertahankan pengeluaran mereka, termasuk pembayaran yang dilakukan melalui Apple Pay. Ini menggunakan data transaksi waktu nyata untuk memungkinkan pelanggan menganalisis pembelanjaan kartu mereka di seluruh periode waktu (mingguan, bulanan, tahunan), menurut kategori (perjalanan, supermarket, uang tunai, dll), dan menurut pengecer.

Dalam posting kami sebelumnya, kami menjelaskan bagaimana Apache Flume dan Apache Kafka digunakan untuk mengubah, memperkaya, dan mengalirkan transaksi ke Apache HBase. Posting ini berlanjut dengan menjelaskan bagaimana transaksi diatur di Apache HBase untuk mengoptimalkan kinerja, dan bagaimana kami menggunakan coprocessors untuk menyediakan agregasi tren pembelian per pelanggan. Santander dan Cloudera melanjutkan (dan masih dalam) perjalanan HBase dengan Spendlytics, perjalanan yang telah melihat banyak iterasi dan pengoptimalan desain skema dan implementasi koprosesor. Kami berharap pelajaran yang dipetik ini adalah poin utama yang dapat diambil dari postingan ini.

Skema 1.0

Desain skema HBase yang baik adalah tentang memahami pola akses yang dimaksud. Lakukan dengan benar dan HBase akan terbang; salah dan Anda bisa berakhir dengan kinerja suboptimal karena pengorbanan desain seperti hotspot wilayah atau harus melakukan pemindaian besar di beberapa wilayah. (Sebuah hotspot dalam tabel HBase adalah tempat distribusi rowkey yang tidak merata dapat menyebabkan sebagian besar permintaan dialihkan ke satu wilayah, membanjiri RegionServer dan mengakibatkan waktu respons yang lambat.)

Apa yang kami ketahui tentang pola akses yang dimaksudkan oleh Spendlytics dan pengaruhnya terhadap desain skema awal:

  • Pelanggan hanya menganalisis transaksi di akun mereka sendiri:
    • Untuk kinerja pemindaian linier yang cepat, semua transaksi pelanggan harus disimpan secara berurutan.
  • ID Pelanggan meningkat secara monoton:
    • ID pelanggan berurutan meningkatkan kemungkinan bahwa pelanggan baru akan ditempatkan bersama dalam wilayah yang sama, yang berpotensi menciptakan hot spot wilayah. Untuk menghindari masalah ini, ID pelanggan harus diberi salt (awalan) atau dibalik agar merata di seluruh wilayah saat digunakan di awal kunci baris.
  • Pelanggan memiliki banyak kartu
    • Untuk mengoptimalkan pemindaian, transaksi pelanggan harus dikelompokkan lebih lanjut dan diurutkan berdasarkan kontrak kartu, yaitu ID kontrak harus menjadi bagian dari kunci baris.
  • Transaksi akan diakses secara keseluruhan, yaitu atribut seperti pengecer, pedagang, lokasi, mata uang, dan jumlah tidak perlu dibaca secara terpisah
    • Menyimpan atribut transaksi dalam sel terpisah akan menghasilkan tabel yang lebih luas dan jarang, yang akan meningkatkan waktu pencarian. Karena atribut akan diakses bersama, masuk akal untuk membuat serial bersama dalam catatan Apache Avro. Avro ringkas dan memberi kami representasi yang efisien dengan kemampuan berkembang skema.
  • Transaksi diakses satu per satu, berkelompok (berdasarkan waktu, kategori, dan pengecer), dan secara agregat (berdasarkan waktu, kategori, dan pengecer).
    • Menambahkan ID transaksi unik sebagai kualifikasi kolom akan memungkinkan pengambilan setiap transaksi tanpa menambah kerumitan pada kunci baris.
    • Untuk mengaktifkan pemindaian transaksi yang cepat selama periode waktu yang bervariasi, stempel waktu transaksi harus menjadi bagian dari kunci baris.
    • Menambahkan kategori dan pengecer ke kunci baris bisa jadi terlalu terperinci dan akan menghasilkan tabel yang sangat tinggi dan sempit dengan kunci baris yang rumit. Tinggi dan sempit boleh saja mengingat bahwa atom tidak menjadi masalah, tetapi menjadikannya sebagai kualifikasi kolom akan memperluas tabel sambil tetap mendukung agregasi sekunder.
  • Data tren harus dihitung terlebih dahulu sebanyak mungkin untuk mengoptimalkan kinerja membaca.
    • Lebih lanjut tentang ini nanti, tetapi untuk saat ini ketahuilah bahwa kami menambahkan keluarga kolom kedua untuk menyimpan tren.

    Berdasarkan hal tersebut di atas, desain skema awal diilustrasikan sebagai berikut:

    Tren Komputasi

    Aspek desain awal yang paling kami pelajari adalah tren komputasi. Persyaratannya adalah untuk memungkinkan pelanggan menganalisis pembelanjaan mereka berdasarkan kategori dan pengecer hingga jam tertentu. Data point tersebut meliputi nilai transaksi terkecil dan terbesar, total nilai transaksi, dan jumlah transaksi. Waktu respons harus 200 md atau kurang.

    Tren pra-komputasi akan memberi kami waktu respons tercepat, jadi ini adalah pendekatan pertama kami. Tren tidak dapat menunda transaksi sehingga harus dihitung pada jalur tulis. Ini akan bagus untuk kinerja membaca, tetapi memberi kami beberapa tantangan:cara terbaik untuk mengatur tren di HBase, dan cara menghitungnya dengan cepat dan andal tanpa terlalu memengaruhi kinerja tulis.

    Kami bereksperimen dengan desain skema yang berbeda dan mencoba memanfaatkan beberapa desain terkenal jika memungkinkan (seperti skema OpenTSDB). Setelah beberapa iterasi, kami menyelesaikan desain skema yang diilustrasikan di atas. Disimpan dalam tabel transaksi, dalam kelompok kolom terpisah, nilai tren diatur bersama dalam satu baris, dengan satu baris tren per pelanggan. Dengan memberikan kunci baris awalan yang sama dengan transaksi pelanggan (misalnya, <reverse_customer_id>::<contract_id> ) memastikan bahwa baris tren akan diurutkan di samping catatan transaksi pelanggan yang sesuai. Dengan penetapan batas wilayah dan kebijakan pemisahan wilayah khusus, kami juga dapat menjamin bahwa baris tren akan selalu ditempatkan bersama dengan catatan transaksi pelanggan, memungkinkan agregasi tren untuk tetap sepenuhnya berada di sisi server dalam koprosesor.

    Untuk menghitung tren sebelumnya, kami menerapkan koprosesor pengamat khusus untuk menghubungkan ke jalur tulis. (Koprosesor pengamat mirip dengan pemicu dalam RDBMS karena mereka mengeksekusi kode pengguna sebelum atau setelah peristiwa tertentu terjadi. Misalnya, sebelum atau sesudah Put atau Get .)

    Di postPut koprosesor melakukan tindakan berikut:

    1. Memeriksa Put untuk atribut tren (bendera). Atribut diatur pada catatan transaksi baru hanya untuk menghindari panggilan rekursif saat memperbarui catatan tren. Ini juga memungkinkan koprosesor dilewati untuk Put s yang tidak memerlukan tren untuk diperbarui (mis. penyelesaian ).
    2. Dapatkan catatan tren untuk pelanggan. Catatan tren pelanggan ditempatkan bersama dengan transaksi mereka (berdasarkan awalan kunci baris) sehingga koprosesor dapat mengambilnya langsung dari wilayah saat ini. Baris tren harus dikunci untuk mencegah beberapa utas pengendali RegionServer mencoba memperbarui tren secara paralel.
    3. Perbarui titik data:
    4. Perbarui dan buka kunci baris tren.

    Solusinya terbukti akurat selama pengujian, dan seperti yang diharapkan, kinerja baca melebihi persyaratan. Namun, ada beberapa kekhawatiran dengan pendekatan ini. Yang pertama adalah bagaimana menangani kegagalan:tren disimpan dalam baris terpisah sehingga atom tidak dapat dijamin. Yang kedua adalah bagaimana memvalidasi keakuratan tren dari waktu ke waktu; yaitu, kita perlu menerapkan mekanisme untuk mengidentifikasi dan memulihkan ketidakakuratan tren apa pun. Ketika kami juga mempertimbangkan persyaratan HA dan fakta bahwa kami perlu menjalankan dua instance HBase aktif-aktif di pusat data yang berbeda, ini bisa menjadi masalah yang lebih besar. Tidak hanya akurasi tren yang menurun dari waktu ke waktu, tetapi dua cluster juga bisa melayang dan harus direkonsiliasi tergantung pada metode yang kami gunakan untuk menyinkronkannya. Terakhir, memperbaiki bug atau menambahkan titik data baru akan sulit karena kami mungkin harus melacak kembali dan menghitung ulang semua tren.

    Lalu ada pertunjukan menulis. Untuk setiap transaksi baru, pengamat harus mengambil catatan tren, memperbarui 32 titik data, dan mengembalikan catatan tren. Meskipun semua ini terjadi dalam batas satu wilayah, kami menemukan bahwa throughput berkurang dari lebih dari 20.000 penulisan per detik menjadi 1.000 penulisan per detik (per RegionServer). Performa ini dapat diterima dalam jangka pendek, tetapi tidak akan diskalakan untuk mendukung beban jangka panjang yang diprediksi.

    Kami tahu bahwa kinerja tulis adalah risiko, jadi kami memiliki rencana cadangan, dan itu adalah koprosesor titik akhir . Koprosesor titik akhir mirip dengan prosedur tersimpan dalam RDBMS karena memungkinkan Anda melakukan komputasi sisi server—di RegionServer tempat data berada, bukan di klien. Endpoint secara efektif memperluas HBase API.

    Alih-alih menghitung tren sebelumnya, titik akhir menghitungnya dengan cepat, di sisi server. Akibatnya, kami dapat menghapus keluarga kolom tren dari skema dan risiko ketidakakuratan dan perbedaan menyertainya. Menjauh dari pengamat menghasilkan kinerja tulis yang baik, tetapi apakah pembacaan cukup cepat? Singkatnya, ya. Dengan transaksi pelanggan yang terbatas pada satu wilayah dan diurutkan berdasarkan kartu dan stempel waktu, titik akhir dapat memindai dan mengagregasi dengan cepat, sesuai dengan target 200 md dari Spendlytics. Ini juga berarti bahwa permintaan klien (dari Spendlytics API dalam kasus ini) hanya pernah dirutekan ke satu instance Endpoint (single RegionServer) dan klien akan mendapatkan satu respons kembali dengan hasil yang lengkap—yaitu, tidak ada sisi klien pemrosesan diperlukan untuk menggabungkan sebagian hasil dari beberapa titik akhir, yang akan terjadi jika transaksi pelanggan menjangkau beberapa wilayah.

    Pelajaran yang Dipetik

    Spendlytics telah aktif sejak Juli 2015. Sejak itu kami telah memantau pola akses dengan cermat dan mencari cara untuk mengoptimalkan kinerja. Kami ingin terus meningkatkan pengalaman pengguna dan memberi pelanggan lebih banyak wawasan tentang pengeluaran kartu mereka. Bagian selanjutnya dari pos ini menjelaskan pelajaran yang telah kami pelajari dari menjalankan Spendlytics dalam produksi dan beberapa pengoptimalan yang telah diterapkan.

    Setelah rilis awal, kami mengidentifikasi sejumlah masalah yang ingin kami fokuskan untuk ditingkatkan. Yang pertama adalah bagaimana memfilter hasil berdasarkan atribut transaksi. Seperti disebutkan sebelumnya, atribut transaksi dikodekan dalam catatan Avro, tetapi kami menemukan bahwa semakin banyak pola akses yang ingin difilter menurut atribut dan pengguna terpaksa melakukan ini di sisi klien. Solusi awalnya adalah mengimplementasikan ValueFilter HBase kustom yang menerima ekspresi filter kompleks kita sendiri, misalnya:

    category='SUPERMARKETS' AND amount > 100 AND 
    (brand LIKE 'foo%' OR brand = 'bar')

    Ekspresi dievaluasi untuk setiap catatan Avro, memungkinkan kami untuk memfilter hasil sisi server dan mengurangi jumlah data yang dikembalikan ke klien (menghemat bandwidth jaringan dan pemrosesan sisi klien). Filter memang memengaruhi kinerja pemindaian, tetapi waktu respons tetap dalam sasaran 200 md.

    Ini akhirnya menjadi solusi sementara karena perubahan lebih lanjut yang diperlukan untuk mengoptimalkan penulisan. Karena cara kerja proses penyelesaian kartu kredit, pertama-tama kami menerima resmi transaksi dari waktu penjualan (hampir real-time) dan kemudian beberapa waktu kemudian dilunasi transaksi dari jaringan kartu kredit (dalam batch). Transaksi ini perlu direkonsiliasi, pada dasarnya dengan menggabungkan yang diselesaikan transaksi dengan resmi transaksi sudah di HBase, bergabung di ID transaksi. Sebagai bagian dari proses ini atribut transaksi dapat berubah dan atribut baru dapat ditambahkan. Ini terbukti menyakitkan karena biaya tambahan karena harus menulis ulang seluruh catatan Avro—bahkan ketika memperbarui atribut tunggal. Jadi untuk membuat atribut lebih mudah diakses untuk pembaruan, kami mengaturnya ke dalam kolom, menggantikan serialisasi Avro.

    Kami juga hanya peduli dengan atomitas tingkat transaksi, jadi mengelompokkan transaksi berdasarkan jam tidak memberi kami keuntungan apa pun. Selain itu, menetap transaksi yang sekarang tiba dalam batch hanya memiliki perincian tingkat hari, yang membuatnya sulit (mahal) untuk merekonsiliasinya dengan resmi yang ada transaksi disimpan per jam. Untuk mengatasi masalah ini, kami memindahkan ID transaksi ke dalam kunci baris dan mengurangi butir stempel waktu menjadi hari, bukan jam. Proses rekonsiliasi sekarang jauh lebih mudah karena kita cukup memuat perubahan secara massal ke HBase dan membiarkan penyelesaian nilai diutamakan.

    Singkatnya:

    • Koprosesor pengamat dapat menjadi alat yang berharga, tetapi gunakanlah dengan bijak.
    • Untuk beberapa kasus penggunaan, memperluas API HBase menggunakan titik akhir adalah alternatif yang baik.
    • Gunakan filter khusus untuk meningkatkan kinerja dengan memangkas hasil di sisi server.
    • Nilai serial masuk akal untuk kasus penggunaan yang tepat, tetapi mainkan kekuatan HBase dengan mendukung dukungan asli untuk bidang dan kolom.
    • Mengelola hasil yang telah dihitung sebelumnya itu sulit; latensi tambahan dari komputasi on-the-fly dapat bermanfaat.
    • Pola akses akan berubah, jadi gesit dan terbuka untuk membuat perubahan pada skema HBase untuk beradaptasi dan tetap terdepan dalam permainan.

    Peta jalan

    Pengoptimalan yang saat ini kami evaluasi adalah koprosesor hybrid. Yang kami maksud dengan ini adalah kombinasi dari pengamat dan koprosesor titik akhir untuk menghitung tren sebelumnya. Namun, tidak seperti sebelumnya, kami tidak akan melakukan ini di jalur tulis tetapi di latar belakang dengan menghubungkan ke operasi pembilasan dan pemadatan HBase. Pengamat akan menghitung tren selama peristiwa penyiraman dan pemadatan berdasarkan penyelesaian transaksi yang tersedia pada saat itu. Kami kemudian akan menggunakan titik akhir untuk menggabungkan tren yang telah dihitung sebelumnya dengan agregasi delta transaksi saat itu juga. Dengan menghitung tren sebelumnya dengan cara ini, kami berharap dapat meningkatkan kinerja membaca, tanpa memengaruhi kinerja tulis.

    Pendekatan lain yang kami evaluasi untuk agregasi tren, dan untuk akses HBase secara umum, adalah Apache Phoenix. Phoenix adalah kulit SQL untuk HBase yang memungkinkan akses menggunakan API JDBC standar. Kami berharap dengan menggunakan SQL dan JDBC akan mempermudah akses HBase dan mengurangi jumlah kode yang harus kita tulis. Kami juga dapat memanfaatkan pola eksekusi cerdas Phoenix dan koprosesor dan filter bawaan untuk agregasi cepat. Phoenix dianggap terlalu tidak matang untuk penggunaan produksi pada permulaan Spendlytics, tetapi dengan kasus penggunaan serupa yang dilaporkan oleh orang-orang seperti eBay dan Salesforce, sekaranglah saatnya untuk mengevaluasi kembali. (Paket Phoenix untuk CDH tersedia untuk instalasi dan evaluasi, tetapi tanpa dukungan, melalui Cloudera Labs.)

    Santander baru-baru ini mengumumkan bahwa itu adalah bank pertama yang meluncurkan teknologi voice banking yang memungkinkan pelanggan untuk berbicara dengan aplikasi SmartBank dan bertanya tentang pengeluaran kartu mereka. Platform di balik teknologi ini adalah Cloudera, dan arsitektur untuk Spendlytics—seperti yang dijelaskan dalam kumpulan postingan ini—berfungsi sebagai desain cetak biru.

    James Kinley adalah Arsitek Solusi Utama di Cloudera.

    Ian Buss adalah Arsitek Solusi Senior di Cloudera.

    Pedro Boado adalah seorang insinyur Hadoop di Santander (Isban) Inggris.

    Abel Fernandez Alfonso adalah seorang insinyur Hadoop di Santander (Isban) Inggris.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Apa itu HBase znodes?

  2. Pengindeksan Email Menggunakan Cloudera Search dan HBase

  3. Pemisahan dan Penggabungan Wilayah Apache HBase

  4. jadi HBase Anda rusak

  5. Apa Selanjutnya untuk Impala Setelah Rilis 1.1