Redis
redis 是一個高性能的 key-value 數據庫。 redis 的出現,很大程度補償了memcached 這類 keyvalue 存儲的不足,在部分場合可以對關係數據庫起到很好的補充作用。它提供了 Python,Ruby,Erlang,PHP 客戶端,使用方便。Redis 的所有數據都是保存在內存中,然後不定期的通過異步方式保存到磁盤上(這稱爲“半持久化模式”);也可以把每一次數據變化都寫入到一個 append only file(aof)裏面(這稱爲“全持久化模式”)。
Redis 由四個可執行文件:redis-benchmark、redis-cli、redis-server、redis-stat 這四個文件,加上一個redis.conf就構成了整個redis的最終可用包。它們的作用如下:
redis-server:Redis服務器的daemon啓動程序
redis-cli:Redis命令行操作工具。當然,你也可以用telnet根據其純文本協議來操作
redis-benchmark:Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫性能
redis-stat:Redis狀態檢測工具,可以檢測Redis當前狀態參數及延遲狀況
1.安裝並配置Redis
tar zxf redis-3.0.2.tar.gz cd redis-3.0.2 yum install -y gcc make make install cd utils/ ./install_server.sh ##啓動腳本 /etc/init.d/redis_6379 restart ##啓動Redis
2.安裝Redis的Php擴展
yum install nginx-1.8.0-1.el6.ngx.x86_64.rpm php-* -y unzip phpredis-master.zip vim /etc/php.ini date.timezone = Asia/Shanghai ##將時區改成亞洲/上海 /etc/init.d/php-fpm restart ##重啓Php vim /etc/php-fpm.d/www.conf ; RPM: apache Choosed to be able to access some dir as httpd user = nginx ##將php-fpm的用戶改爲nginx ; RPM: Keep a group allowed to write in log dir. group = nginx ##將php-fpm的用戶組改爲nginx cd phpredis-master/ phpize ./configure ##編譯 make && make install ##安裝 cd /etc/php.d/ cp mysql.ini redis.ini vim redis.ini extension=redis.so /etc/init.d/php-fpm restart ##重啓php
3.配置Nginx
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name; include fastcgi_params; } /etc/init.d/nginx restart ##重啓Nginx
4.配置Mysql並測試
/etc/init.d/mysqld start ##啓動數據庫 mysql mysql> grant all on *.* to redis@localhost identified by 'westos'; Query OK, 0 rows affected (0.00 sec) mysql> quit Bye cd redis/ mysql < test.sql ##將測試數據庫導入Mysql mysql mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from test; +----+-------+ | id | name | +----+-------+ | 1 | test1 | | 2 | test2 | | 3 | test3 | | 4 | test4 | | 5 | test5 | | 6 | test6 | | 7 | test7 | | 8 | test8 | | 9 | test9 | +----+-------+ 9 rows in set (0.00 sec)
登陸172.25.35.6測試,如圖:
我們實現了redis作爲mysql的緩存服務器,但是如果更新了mysql,redis中仍然會有對應的 KEY,數據就不會更新,此時就會出現mysql和redis數據不一致的情況。所以接下來就要通過 mysql 觸發器將改變的數據同步到redis中。
我們可以通過Gearman來實現數據同步:
Gearman 是一個支持分佈式的任務分發框架:
Gearman Job Server:Gearman 核心程序,需要編譯安裝並以守護進程形式運行在後臺。
Gearman Client:可以理解爲任務的請求者。
Gearman Worker:任務的真正執行者,一般需要自己編寫具體邏輯並通過守護進程方式
運行,Gearman Worker 接收到 Gearman Client 傳遞的任務內容後,會按順序處理。
5.安裝並且配置Gearman
cd redis/ yum install gcc libgearman-devel-1.1.8-2.el6.x86_64.rpm libevent-devel-1.4.13-4.el6.x86_64.rpm libevent-doc-1.4.13-4.el6.noarch.rpm libevent-headers-1.4.13-4.el6.noarch.rpm libgearman-1.1.8-2.el6.x86_64.rpm tokyocabinet-1.4.33-6.el6.x86_64.rpm cd gearman-1.1.2/ ./configure make && make install
6.安裝lib_mysqludf_json
lib_mysqludf_json UDF 庫函數將關係數據映射爲 JSON 格式。通常,數據庫中的數據映射爲 JSON 格式,是通過程序來轉換的。
unzip lib_mysqludf_json-master.zip cd lib_mysqludf_json-master/ gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c mysql mysql> show global variables like 'plugin_dir'; +---------------+-------------------------+ | Variable_name | Value | +---------------+-------------------------+ | plugin_dir | /usr/lib64/mysql/plugin | +---------------+-------------------------+ 1 row in set (0.00 sec) cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/ ##拷貝lib_mysqludf_json.so模塊 mysql> create function json_object returns string soname -> 'lib_mysqludf_json.so'; ##註冊UDF函數
7.安裝gearman-mysql-udf來管理調用gearman
tar zxf gearman-mysql-udf-0.6.tar.gz cd gearman-mysql-udf-0.6/ yum install -y gcc-c++ ./configure --libdir=/usr/lib64/mysql/plugin/ make && make install mysql mysql> create function gman_do_background returns string soname 'lib_mysqludf_json.so'; ##註冊UDF函數 mysql> create function gman_servers_set returns string soname 'lib_mysqludf_json.so'; mysql> select * from mysql.func; +--------------------+-----+-------------------------+----------+ | name | ret | dl | type | +--------------------+-----+-------------------------+----------+ | json_object | 0 | lib_mysqludf_json.so | function | | gman_do_background | 0 | libgearman_mysql_udf.so | function | | gman_servers_set | 0 | libgearman_mysql_udf.so | function | +--------------------+-----+-------------------------+----------+ 3 rows in set (0.00 sec) ##查看註冊的函數 mysql> select gman_servers_set('127.0.0.1:4730'); ##指定Gearman的服務信息 +------------------------------------+ | gman_servers_set('127.0.0.1:4730') | +------------------------------------+ | 127.0.0.1:4730 | +------------------------------------+ 1 row in set (0.00 sec) mysql> quit Bye vim /root/redis/test.sql use test; #CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; #INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9'); DELIMITER $$ ##編寫Mysql的觸發器 CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`)); END$$ DELIMITER ; mysql < test.sql ##將檢測數據庫導入mysql mysql mysql> SHOW TRIGGERS FROM test; ##查看觸發器 +-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+ | Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation | +-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+ | datatoredis | UPDATE | test | BEGIN SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`)); END | AFTER | NULL | | root@localhost | latin1 | latin1_swedish_ci | latin1_swedish_ci | +-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+ 1 row in set (0.00 sec)
8.配置Gearman的worker端
cp worker.php /usr/local/bin/ cd /usr/local/bin/ nohup php worker.php & [1] 9068 ##將worker打入後臺運行 vim worker.php <?php $worker = new GearmanWorker(); $worker->addServer(); $worker->addFunction('syncToRedis', 'syncToRedis'); $redis = new Redis(); $redis->connect('127.0.0.1', 6379); while($worker->work()); function syncToRedis($job) { global $redis; $workString = $job->workload(); $work = json_decode($workString); if(!isset($work->id)){ return false; } $redis->set($work->id, $work->name); } ?>
9.更新Mysql中的數據並檢測
mysql mysql> use test; mysql> update test set name='hello' where id=1; Query OK, 1 row affected (0.12 sec) mysql> update test set name='world' where id=2; Query OK, 1 row affected (0.06 sec) mysql> select * from test; +----+-------+ | id | name | +----+-------+ | 1 | hello | | 2 | world | | 3 | test3 | | 4 | test4 | | 5 | test5 | | 6 | test6 | | 7 | test7 | | 8 | test8 | | 9 | test9 | +----+-------+ 9 rows in set (0.00 sec) mysql> quit Bye 如圖:
10.主從複製
master:172.25.35.6 slave:172.25.35.7 172.25.35.8 在slave端: vim /etc/redis/6379.conf slaveof 172.25.35.6 6379 測試: [root@server6 bin]# redis-cli 127.0.0.1:6379> set 1 westos OK 127.0.0.1:6379> get 1 "westos" [root@server7 redis-3.0.2]# redis-cli 127.0.0.1:6379> get 1 "westos" [root@server8 ~]# redis-cli 127.0.0.1:6379> get 1 "westos"