No | Nama | Keterangan | Jumlah |
---|---|---|---|
1 | OS Host | Ubuntu 18.04 | 1 Node |
2 | VM MySQL Cluster | Ubuntu 16.04 | 4 Node |
3 | VM Redis Cluster | Ubuntu 16.04 | 3 Node |
4 | MongoDB Atlas | - | 3 Node |
5 | Aplikasi | Laravel 5.6 | - |
-
Dokumentasi https://github.com/cphikmawan
-
Konfigurasi Koneksi, file .env
DB_CONNECTION=mysql
DB_HOST=192.168.33.10
DB_PORT=6033
DB_DATABASE=dbeasapp
DB_USERNAME=easapp
DB_PASSWORD=easapp
- MVC Aplikasi menggunakan CRUD biasa
-
MongoDB Atlas https://cloud.mongodb.com/
-
Install MongoDB Driver untuk Laravel
composer require jenssegers/mongodb
-
Konfigurasi Koneksi, file .env
MONGO_DB_HOST=127.0.0.1 MONGO_DB_PORT=27017 MONGO_DB_DATABASE=pageviews MONGO_DB_USERNAME= MONGO_DB_PASSWORD=
-
Konfigurasi Koneksi, file config/database.php
. . 'connections' => [ 'mongodb' => [ 'driver' => 'mongodb', 'dsn'=>'mongodb://cloudy:sembarang12@cloudcluster0-shard-00-00-tiugx.mongodb.net:27017,cloudcluster0-shard-00-01-tiugx.mongodb.net:27017,cloudcluster0-shard-00-02-tiugx.mongodb.net:27017/test?ssl=true&replicaSet=CloudCluster0-shard-0&authSource=admin&retryWrites=true', 'database' => 'pageviews', ], . . . ],
-
Setelah Melakukan "vagrant up"
-
Node 1
-
Membuat Konfigurasi master.conf
bind 0.0.0.0 port 6379 cluster-enabled yes cluster-config-file redis-node-1.conf cluster-node-timeout 5000 appendonly yes appendfilename redis-1.aof dbfilename redis-1.rdb
-
Membuat Konfigurasi slave.conf
bind 0.0.0.0 port 6381 cluster-enabled yes cluster-config-file redis-node-4.conf cluster-node-timeout 5000 appendonly yes appendfilename redis-4.aof dbfilename redis-4.rdb
-
Melakukan Koneksi dan disimpan di background
# Connection redis-server /vagrant/redis-cluster/configure/node1/master.conf > /dev/null 2>&1 & redis-server /vagrant/redis-cluster/configure/node1/slave.conf > /dev/null 2>&1 &
-
Membuat Cluster
redis-cli --cluster create 192.168.33.21:6379 192.168.33.22:6380 192.168.33.23:6381
-
Koneksi Slave ke Master
redis-cli --cluster add-node 192.168.33.21:6381 192.168.33.23:6381 --cluster-slave
-
-
Node 2
-
Membuat Konfigurasi master.conf
bind 0.0.0.0 port 6380 cluster-enabled yes cluster-config-file redis-node-2.conf cluster-node-timeout 5000 appendonly yes appendfilename redis-2.aof dbfilename redis-2.rdb
-
Membuat Konfigurasi slave.conf
bind 0.0.0.0 port 6379 cluster-enabled yes cluster-config-file redis-node-5.conf cluster-node-timeout 5000 appendonly yes appendfilename redis-5.aof dbfilename redis-5.rdb
-
Melakukan Koneksi dan disimpan di background
redis-server /vagrant/redis-cluster/configure/node2/master.conf > /dev/null 2>&1 & redis-server /vagrant/redis-cluster/configure/node2/slave.conf > /dev/null 2>&1 &
-
Membuat Cluster
redis-cli --cluster create 192.168.33.21:6379 192.168.33.22:6380 192.168.33.23:6381
-
Koneksi Slave ke Master
redis-cli --cluster add-node 192.168.33.22:6379 192.168.33.21:6379 --cluster-slave
-
-
Node 3
-
Membuat Konfigurasi master.conf
bind 0.0.0.0 port 6381 cluster-enabled yes cluster-config-file redis-node-3.conf cluster-node-timeout 5000 appendonly yes appendfilename redis-3.aof dbfilename redis-3.rdb
-
Membuat Konfigurasi slave.conf
bind 0.0.0.0 port 6380 cluster-enabled yes cluster-config-file redis-node-6.conf cluster-node-timeout 5000 appendonly yes appendfilename redis-6.aof dbfilename redis-6.rdb
-
Melakukan Koneksi dan disimpan di background
redis-server /vagrant/redis-cluster/configure/node3/master.conf > /dev/null 2>&1 & redis-server /vagrant/redis-cluster/configure/node3/slave.conf > /dev/null 2>&1 &
-
Membuat Cluster
redis-cli --cluster create 192.168.33.21:6379 192.168.33.22:6380 192.168.33.23:6381
-
Koneksi Slave ke Master
redis-cli --cluster add-node 192.168.33.23:6380 192.168.33.22:6380 --cluster-slave
-
-
Cluster siap digunakan
Tidak membuat replica
-
Koneksi MySQL Cluster sudah dijelaskan di step sebelumnya
-
Koneksi MongoDB Atlas sudah dijelaskan di step sebelumnya
- Untuk file Model yang akan digunakan harus ditambahkan driver yang sudah diinstall sebelumnya
- File Model Pages.php
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Jenssegers\Mongodb\Eloquent\Model as Eloquent; class Pages extends Eloquent { protected $connection = 'mongodb'; protected $collection = 'countviews'; protected $fillable = [ 'key', 'name', 'count' ]; }
- Controller dan Views tidak diperlukan config tambahan
-
Koneksi ke Redis Cluster menggunakan API yang dibuat dengan Python Flask
from flask import Flask, request, jsonify from json import dumps, loads from rediscluster import StrictRedisCluster app = Flask(__name__) redis_nodes = [{"host": "192.168.33.21", "port": "6379"}, {"host": "192.168.33.22", "port": "6380"}, {"host": "192.168.33.23", "port": "6381"}] rc = StrictRedisCluster(startup_nodes=redis_nodes, decode_responses=True) # add page for count @app.route('/api/page/zadd/<page_id>', methods=['POST']) def addPage(page_id): pattern = 'page:'+page_id+':' insert = rc.zadd('Views', 0, pattern) return dumps(insert) # increment page count @app.route('/api/page/incr/<page_id>', methods=['POST']) def incrPage(page_id): pattern = 'page:'+page_id+':' insert = rc.zincrby('Views', pattern, 1.0) return dumps(insert) # get increment value @app.route('/api/page/get_incr/<page_id>', methods=['GET']) def getIncrPages(page_id): pattern = 'page:'+page_id+':' res = [] get_data = rc.zscore('Views', pattern) res.append(get_data) return dumps(res) # get rank @app.route('/api/page/get_rank/', methods=['GET']) def getRange(): res = [] get_data = rc.zrange('Views', 0, -1, 'DESC', 'WITHSCORES' ) print (get_data) res.append(get_data) return dumps(res) if __name__ == '__main__': app.run(debug=True)
-
Install GuzzleHttp untuk koneksi ke API
composer require guzzlehttp/guzzle:~6.0
-
PagesController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Pages; use GuzzleHttp\Client; class PageController extends Controller { public function index() { $pages = Pages::all(); return view('pageviews.index',compact('pages', 'res')); } public function create() { return view('pageviews.create'); } public function store(Request $request) { // save to mongo $page = new Pages(); $page->key = $request->get('key'); $page->name = $request->get('name'); $page->count = 0; $page->save(); $client = new Client(); $increment = $client->post('http://localhost:5000/api/page/zadd/'.$page->id); return redirect('/pagelist')->with('success', 'New Page Added'); } public function ranking() { // $pages = Pages::orderBy('count', 'desc')->get(); $client = new Client(); $res = $client->get('http://localhost:5000/api/page/get_rank/')->getBody(); $res = json_decode($res); // dd($res); return view('pageviews.ranking',compact('res')); } public function pages($id) { // save to mongo $page = Pages::find($id); $page->increment('count'); // redis $client = new Client(); $increment = $client->post('http://localhost:5000/api/page/incr/'.$page->id); $res = $client->get('http://localhost:5000/api/page/get_incr/'.$page->id)->getBody(); $res = json_decode($res); return view('pageviews.page',compact('page', 'res')); } }
Command untuk demo
SELECT * FROM performance_schema.replication_group_members;
SET GLOBAL group_replication_bootstrap_group=OFF;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=ON;
-
Listen Server Flask
python redisapi.py
-
Listen Development Server Laravel
php artisan serve --port 9000
-
Akses http://localhost:9000
-
Tambah Data Buku
-
Tambah Page
-
Increment Page
-
Check Redis
-
Ranking Redis
-
Ranking MongoDB