Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Beban Kerja Database OLTP/Analytics Hibrida:Mereplikasi Data MySQL ke ClickHouse

Bagaimana cara menjalankan Analytics di MySQL?

MySQL adalah database yang bagus untuk beban kerja Pemrosesan Transaksi Online (OLTP). Untuk beberapa perusahaan, dulu lebih dari cukup untuk waktu yang lama. Waktu telah berubah dan persyaratan bisnis bersama mereka. Karena bisnis bercita-cita untuk menjadi lebih didorong oleh data, semakin banyak data yang disimpan untuk analisis lebih lanjut; perilaku pelanggan, pola kinerja, lalu lintas jaringan, log, dll. Tidak peduli apa industri Anda, kemungkinan besar ada data yang ingin Anda simpan dan analisis untuk lebih memahami apa yang sedang terjadi dan bagaimana meningkatkan bisnis Anda. Sayangnya, untuk menyimpan dan menanyakan data dalam jumlah besar, MySQL bukanlah pilihan terbaik. Tentu, ia dapat melakukannya dan memiliki alat untuk membantu mengakomodasi data dalam jumlah besar (misalnya, kompresi InnoDB), tetapi menggunakan solusi khusus untuk Pemrosesan Analisis Online (OLAP) kemungkinan besar akan sangat meningkatkan kemampuan Anda untuk menyimpan dan melakukan kueri dalam jumlah besar data.

Salah satu cara untuk mengatasi masalah ini adalah dengan menggunakan database khusus untuk menjalankan analitik. Biasanya, Anda ingin menggunakan penyimpanan data berbentuk kolom untuk tugas seperti itu - mereka lebih cocok untuk menangani data dalam jumlah besar:data yang disimpan dalam kolom biasanya lebih mudah dikompresi, juga lebih mudah diakses per kolom - biasanya Anda meminta beberapa data disimpan dalam beberapa kolom - kemampuan untuk mengambil hanya kolom tersebut alih-alih membaca semua baris dan menyaring data yang tidak dibutuhkan membuat data diakses lebih cepat.

Bagaimana Cara Mereplikasi Data Dari MySQL ke ClickHouse?

Contoh penyimpanan data kolom yang cocok untuk analitik adalah ClickHouse, penyimpanan kolom sumber terbuka. Salah satu tantangannya adalah memastikan data di ClickHouse sinkron dengan data di MySQL. Tentu, selalu mungkin untuk menyiapkan semacam pipa data dan melakukan pemuatan batch otomatis ke ClickHouse. Tetapi selama Anda dapat hidup dengan beberapa keterbatasan, ada cara yang lebih baik untuk menyiapkan replikasi hampir real-time dari MySQL ke ClickHouse. Dalam posting blog ini kita akan melihat bagaimana hal itu dapat dilakukan.

Instalasi ClickHouse

Pertama-tama kita perlu menginstal ClickHouse. Kami akan menggunakan panduan memulai dari situs web ClickHouse.

sudo apt-get install dirmngr    # optional
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4    # optional

echo "deb http://repo.yandex.ru/clickhouse/deb/stable/ main/" | sudo tee /etc/apt/sources.list.d/clickhouse.list
sudo apt-get update
sudo apt-get install -y clickhouse-server clickhouse-client
sudo service clickhouse-server start

Setelah ini selesai, kita perlu mencari cara untuk mentransfer data dari MySQL ke ClickHouse. Salah satu solusi yang mungkin adalah dengan menggunakan clickhouse-mysql-data-reader Altinity. Pertama-tama, kita harus menginstal pip3 (python3-pip di Ubuntu) karena Python dalam versi setidaknya 3.4 diperlukan. Kemudian kita dapat menggunakan pip3 untuk menginstal beberapa modul Python yang diperlukan:

pip3 install mysqlclient
pip3 install mysql-replication
pip3 install clickhouse-driver

Setelah ini selesai, kita harus mengkloning repositori. Untuk Centos 7, RPM juga tersedia, juga dimungkinkan untuk menginstalnya menggunakan pip3 (paket clickhouse-mysql) tetapi kami menemukan bahwa versi yang tersedia melalui pip tidak berisi pembaruan terbaru dan kami ingin menggunakan cabang master dari repositori git:

git clone https://github.com/Altinity/clickhouse-mysql-data-reader

Kemudian, kita dapat menginstalnya menggunakan pip:

pip3 install -e /path/to/clickhouse-mysql-data-reader/

Langkah selanjutnya adalah membuat pengguna MySQL yang dibutuhkan oleh clickhouse-mysql-data-reader untuk mengakses data MySQL:

mysql> CREATE USER 'chreader'@'%' IDENTIFIED BY 'pass';
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE USER 'chreader'@'127.0.0.1' IDENTIFIED BY 'pass';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE USER 'chreader'@'localhost' IDENTIFIED BY 'pass';
Query OK, 0 rows affected (0.02 sec)
mysql> GRANT SELECT, REPLICATION CLIENT, REPLICATION SLAVE, SUPER ON *.* TO 'chreader'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT SELECT, REPLICATION CLIENT, REPLICATION SLAVE, SUPER ON *.* TO 'chreader'@'127.0.0.1';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT SELECT, REPLICATION CLIENT, REPLICATION SLAVE, SUPER ON *.* TO 'chreader'@'localhost';
Query OK, 0 rows affected, 1 warning (0.01 sec)

Anda juga harus meninjau konfigurasi MySQL Anda untuk memastikan Anda mengaktifkan log biner, max_binlog_size diatur ke 768M, binlog dalam format 'baris' dan alat tersebut dapat terhubung ke MySQL. Di bawah ini adalah kutipan dari dokumentasi:

[mysqld]
# mandatory
server-id        = 1
log_bin          = /var/lib/mysql/bin.log
binlog-format    = row # very important if you want to receive write, update and delete row events
# optional
expire_logs_days = 30
max_binlog_size  = 768M
# setup listen address
bind-address     = 0.0.0.0

Mengimpor Data

Ketika semuanya sudah siap, Anda dapat mengimpor data ke ClickHouse. Idealnya Anda akan menjalankan impor pada host dengan tabel terkunci sehingga tidak ada perubahan yang akan terjadi selama proses. Anda dapat menggunakan budak sebagai sumber data. Perintah yang akan dijalankan adalah:

clickhouse-mysql --src-server-id=1 --src-wait --nice-pause=1 --src-host=10.0.0.142 --src-user=chreader --src-password=pass --src-tables=wiki.pageviews --dst-host=127.0.0.1 --dst-create-table --migrate-table

Ini akan terhubung ke MySQL pada host 10.0.0.142 menggunakan kredensial yang diberikan, itu akan menyalin tabel 'tampilan halaman' dalam skema 'wiki' ke ClickHouse yang berjalan di host lokal (127.0.0.1). Tabel akan dibuat secara otomatis dan data akan dimigrasikan.

Untuk tujuan blog ini, kami mengimpor sekitar 50 juta baris dari kumpulan data "tampilan halaman" yang disediakan oleh Wikimedia Foundation. Skema tabel di MySQL adalah:

mysql> SHOW CREATE TABLE wiki.pageviews\G
*************************** 1. row ***************************
       Table: pageviews
Create Table: CREATE TABLE `pageviews` (
  `date` date NOT NULL,
  `hour` tinyint(4) NOT NULL,
  `code` varbinary(255) NOT NULL,
  `title` varbinary(1000) NOT NULL,
  `monthly` bigint(20) DEFAULT NULL,
  `hourly` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`date`,`hour`,`code`,`title`)
) ENGINE=InnoDB DEFAULT CHARSET=binary
1 row in set (0.00 sec)

Alat ini menerjemahkan ini ke dalam skema ClickHouse berikut:

vagrant.vm :) SHOW CREATE TABLE wiki.pageviews\G

SHOW CREATE TABLE wiki.pageviews

Row 1:
──────
statement: CREATE TABLE wiki.pageviews ( date Date,  hour Int8,  code String,  title String,  monthly Nullable(Int64),  hourly Nullable(Int64)) ENGINE = MergeTree(date, (date, hour, code, title), 8192)

1 rows in set. Elapsed: 0.060 sec.

Setelah impor selesai, kita dapat membandingkan isi MySQL:

mysql> SELECT COUNT(*) FROM wiki.pageviews\G
*************************** 1. row ***************************
COUNT(*): 50986914
1 row in set (24.56 sec)

dan di ClickHouse:

vagrant.vm :) SELECT COUNT(*) FROM wiki.pageviews\G

SELECT COUNT(*)
FROM wiki.pageviews

Row 1:
──────
COUNT(): 50986914

1 rows in set. Elapsed: 0.014 sec. Processed 50.99 million rows, 50.99 MB (3.60 billion rows/s., 3.60 GB/s.)

Bahkan dalam tabel sekecil itu, Anda dapat dengan jelas melihat bahwa MySQL membutuhkan lebih banyak waktu untuk memindainya daripada ClickHouse.

Saat memulai proses untuk menonton log biner untuk peristiwa, idealnya Anda akan meneruskan informasi tentang file log biner dan posisi dari mana alat harus mulai mendengarkan. Anda dapat dengan mudah memeriksanya di slave setelah impor awal selesai.

clickhouse-mysql --src-server-id=1 --src-resume --src-binlog-file='binlog.000016' --src-binlog-position=194 --src-wait --nice-pause=1 --src-host=10.0.0.142 --src-user=chreader --src-password=pass --src-tables=wiki.pageviews --dst-host=127.0.0.1 --pump-data --csvpool

Jika Anda tidak lulus, itu hanya akan mulai mendengarkan apa pun yang masuk:

clickhouse-mysql --src-server-id=1 --src-resume --src-wait --nice-pause=1 --src-host=10.0.0.142 --src-user=chreader --src-password=pass --src-tables=wiki.pageviews --dst-host=127.0.0.1 --pump-data --csvpool

Mari muat lebih banyak data dan lihat bagaimana hasilnya untuk kita. Kita dapat melihat bahwa semuanya tampak baik-baik saja dengan melihat log clickhouse-mysql-data-reader:

2019-02-11 15:21:29,705/1549898489.705732:INFO:['wiki.pageviews']
2019-02-11 15:21:29,706/1549898489.706199:DEBUG:class:<class 'clickhouse_mysql.writer.poolwriter.PoolWriter'> insert
2019-02-11 15:21:29,706/1549898489.706682:DEBUG:Next event binlog pos: binlog.000016.42066434
2019-02-11 15:21:29,707/1549898489.707067:DEBUG:WriteRowsEvent #224892 rows: 1
2019-02-11 15:21:29,707/1549898489.707483:INFO:['wiki.pageviews']
2019-02-11 15:21:29,707/1549898489.707899:DEBUG:class:<class 'clickhouse_mysql.writer.poolwriter.PoolWriter'> insert
2019-02-11 15:21:29,708/1549898489.708083:DEBUG:Next event binlog pos: binlog.000016.42066595
2019-02-11 15:21:29,708/1549898489.708659:DEBUG:WriteRowsEvent #224893 rows: 1

Yang harus kita ingat adalah keterbatasan alat. Yang terbesar adalah hanya mendukung INSERT. Tidak ada dukungan untuk DELETE atau UPDATE. Juga tidak ada dukungan untuk DDL sehingga setiap perubahan skema yang tidak kompatibel yang dijalankan di MySQL akan merusak replikasi MySQL ke ClickHouse.

Juga perlu diperhatikan adalah fakta bahwa pengembang skrip merekomendasikan untuk menggunakan pypy untuk meningkatkan kinerja alat. Mari kita lakukan beberapa langkah yang diperlukan untuk menyiapkannya.

Pertama-tama Anda harus mengunduh dan mendekompresi pypy:

wget https://bitbucket.org/squeaky/portable-pypy/downloads/pypy3.5-7.0.0-linux_x86_64-portable.tar.bz2
tar jxf pypy3.5-7.0.0-linux_x86_64-portable.tar.bz2
cd pypy3.5-7.0.0-linux_x86_64-portable

Selanjutnya, kita harus menginstal pip dan semua persyaratan untuk clickhouse-mysql-data-reader - hal yang sama persis seperti yang kita bahas sebelumnya, saat menjelaskan penyiapan reguler:

./bin/pypy -m ensurepip
./bin/pip3 install mysql-replication
./bin/pip3 install clickhouse-driver
./bin/pip3 install mysqlclient

Langkah terakhir adalah menginstal clickhouse-mysql-data-reader dari repositori github (kami menganggapnya telah dikloning):

./bin/pip3 install -e /path/to/clickhouse-mysql-data-reader/

Itu saja. Mulai sekarang Anda harus menjalankan semua perintah menggunakan lingkungan yang dibuat untuk pypy:

./bin/pypy ./bin/clickhouse-mysql

Tes

Data telah dimuat, kami dapat memverifikasi bahwa semuanya berjalan lancar dengan membandingkan ukuran tabel:

MySQL:

mysql> SELECT COUNT(*) FROM wiki.pageviews\G
*************************** 1. row ***************************
COUNT(*): 204899465
1 row in set (1 min 40.12 sec)

ClickHouse:

vagrant.vm :) SELECT COUNT(*) FROM wiki.pageviews\G

SELECT COUNT(*)
FROM wiki.pageviews

Row 1:
──────
COUNT(): 204899465

1 rows in set. Elapsed: 0.100 sec. Processed 204.90 million rows, 204.90 MB (2.04 billion rows/s., 2.04 GB/s.)

Semuanya terlihat benar. Mari kita jalankan beberapa kueri untuk melihat bagaimana ClickHouse berperilaku. Harap diingat bahwa semua penyiapan ini jauh dari tingkat produksi. Kami menggunakan dua VM kecil, memori 4GB, masing-masing satu vCPU. Oleh karena itu meskipun datasetnya tidak besar, sudah cukup untuk melihat perbedaannya. Karena sampelnya kecil, cukup sulit untuk melakukan analitik "nyata", tetapi kami masih dapat mengajukan beberapa kueri acak.

Mari kita periksa hari apa dalam seminggu kami memiliki data dan berapa banyak halaman yang telah dilihat per hari dalam data sampel kami:

vagrant.vm :) SELECT count(*), toDayOfWeek(date) AS day FROM wiki.pageviews GROUP BY day ORDER BY day ASC;

SELECT
    count(*),
    toDayOfWeek(date) AS day
FROM wiki.pageviews
GROUP BY day
ORDER BY day ASC

┌───count()─┬─day─┐
│  50986896 │   2 │
│ 153912569 │   3 │
└───────────┴─────┘

2 rows in set. Elapsed: 2.457 sec. Processed 204.90 million rows, 409.80 MB (83.41 million rows/s., 166.82 MB/s.)

Dalam kasus MySQL, kueri ini terlihat seperti di bawah ini:

mysql> SELECT COUNT(*), DAYOFWEEK(date) AS day FROM wiki.pageviews GROUP BY day ORDER BY day;
+-----------+------+
| COUNT(*)  | day  |
+-----------+------+
|  50986896 |    3 |
| 153912569 |    4 |
+-----------+------+
2 rows in set (3 min 35.88 sec)

Seperti yang Anda lihat, MySQL membutuhkan 3,5 menit untuk melakukan pemindaian tabel secara penuh.

Sekarang, mari kita lihat berapa banyak halaman yang memiliki nilai bulanan lebih besar dari 100:

vagrant.vm :) SELECT count(*), toDayOfWeek(date) AS day FROM wiki.pageviews WHERE  monthly > 100 GROUP BY day;

SELECT
    count(*),
    toDayOfWeek(date) AS day
FROM wiki.pageviews
WHERE monthly > 100
GROUP BY day

┌─count()─┬─day─┐
│   83574 │   2 │
│  246237 │   3 │
└─────────┴─────┘

2 rows in set. Elapsed: 1.362 sec. Processed 204.90 million rows, 1.84 GB (150.41 million rows/s., 1.35 GB/s.)

Dalam kasus MySQL lagi 3,5 menit:

mysql> SELECT COUNT(*), DAYOFWEEK(date) AS day FROM wiki.pageviews WHERE YEAR(date) = 2018 AND monthly > 100 GROUP BY day;
^@^@+----------+------+
| COUNT(*) | day  |
+----------+------+
|    83574 |    3 |
|   246237 |    4 |
+----------+------+
2 rows in set (3 min 3.48 sec)

Kueri lain, hanya pencarian berdasarkan beberapa nilai string:

vagrant.vm :) select * from wiki.pageviews where title LIKE 'Main_Page' AND code LIKE 'de.m' AND hour=6;

SELECT *
FROM wiki.pageviews
WHERE (title LIKE 'Main_Page') AND (code LIKE 'de.m') AND (hour = 6)

┌───────date─┬─hour─┬─code─┬─title─────┬─monthly─┬─hourly─┐
│ 2018-05-01 │    6 │ de.m │ Main_Page │       8 │      0 │
└────────────┴──────┴──────┴───────────┴─────────┴────────┘
┌───────date─┬─hour─┬─code─┬─title─────┬─monthly─┬─hourly─┐
│ 2018-05-02 │    6 │ de.m │ Main_Page │      17 │      0 │
└────────────┴──────┴──────┴───────────┴─────────┴────────┘

2 rows in set. Elapsed: 0.015 sec. Processed 66.70 thousand rows, 4.20 MB (4.48 million rows/s., 281.53 MB/s.)

Permintaan lain, melakukan beberapa pencarian dalam string dan kondisi berdasarkan kolom 'bulanan':

vagrant.vm :) select title from wiki.pageviews where title LIKE 'United%Nations%' AND code LIKE 'en.m' AND monthly>100 group by title;

SELECT title
FROM wiki.pageviews
WHERE (title LIKE 'United%Nations%') AND (code LIKE 'en.m') AND (monthly > 100)
GROUP BY title

┌─title───────────────────────────┐
│ United_Nations                  │
│ United_Nations_Security_Council │
└─────────────────────────────────┘

2 rows in set. Elapsed: 0.083 sec. Processed 1.61 million rows, 14.62 MB (19.37 million rows/s., 175.34 MB/s.)

Dalam kasus MySQL terlihat seperti di bawah ini:

mysql> SELECT * FROM wiki.pageviews WHERE title LIKE 'Main_Page' AND code LIKE 'de.m' AND hour=6;
+------------+------+------+-----------+---------+--------+
| date       | hour | code | title     | monthly | hourly |
+------------+------+------+-----------+---------+--------+
| 2018-05-01 |    6 | de.m | Main_Page |       8 |      0 |
| 2018-05-02 |    6 | de.m | Main_Page |      17 |      0 |
+------------+------+------+-----------+---------+--------+
2 rows in set (2 min 45.83 sec)

Jadi, hampir 3 menit. Kueri kedua sama:

mysql> select title from wiki.pageviews where title LIKE 'United%Nations%' AND code LIKE 'en.m' AND monthly>100 group by title;
+---------------------------------+
| title                           |
+---------------------------------+
| United_Nations                  |
| United_Nations_Security_Council |
+---------------------------------+
2 rows in set (2 min 40.91 sec)

Tentu saja, orang dapat berargumen bahwa Anda dapat menambahkan lebih banyak indeks untuk meningkatkan kinerja kueri, tetapi kenyataannya, menambahkan indeks akan memerlukan data tambahan untuk disimpan di disk. Indeks membutuhkan ruang disk dan juga menimbulkan tantangan operasional - jika kita berbicara tentang kumpulan data OLAP dunia nyata, kita berbicara tentang terabyte data. Dibutuhkan banyak waktu dan membutuhkan proses yang terdefinisi dengan baik dan teruji untuk menjalankan perubahan skema pada lingkungan tersebut. Inilah sebabnya mengapa penyimpanan data kolumnar khusus bisa sangat berguna dan sangat membantu untuk mendapatkan wawasan yang lebih baik tentang semua data analitik yang disimpan semua orang.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kapan menggunakan tanda kutip tunggal, tanda kutip ganda, dan tanda kutip di MySQL

  2. Bagaimana cara mengubah baris tabel mysql menjadi kolom

  3. Penanganan &Pembatasan Koneksi dengan ProxySQL

  4. Kinerja tampilan MySql

  5. Setara dengan RowID Oracle di MySQL