redis缓存


安装


下载redis-4.0.8.tar.gz
我这里使用4.0.8的
解压 下载gcc
进入解压目录 make && make installl
这里写图片描述

vim /etc/redis/6379.conf 
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 0.0.0.0   #更改为0.0.0.0  监听本机所有端口

# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of 

这里写图片描述
同步 在server2 上面 进行同步
这里写图片描述
这里写图片描述


redis 集群搭建


port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
pidfile /usr/local/cluster/7001/redis.pid
logfile /usr/local/cluster/7001/redis.log
~                                        

文件中的 cluster-enabled 选项用于开实例的集群模式, 而 cluster-conf-file 选项则设定了保存节点配置文件的路径, 默认值为 nodes.conf.节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新。

要让集群正常运作至少需要三个主节点,不过在刚开始试用集群功能时, 强烈建议使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。

首先, 让我们进入一个新目录, 并创建六个以端口号为名字的子目录, 稍后我们在将每个目录中运行一个 Redis 实例: 命令如下:

[root@server1 ~]# cd /usr/local/
[root@server1 local]# mkdir cluster
[root@server1 local]# cd cluster/
[root@server1 cluster]# mkdir 7001
[root@server1 cluster]# mkdir 7002
[root@server1 cluster]# mkdir 7003
[root@server1 cluster]# mkdir 7004
[root@server1 cluster]# mkdir 7005
[root@server1 cluster]# mkdir 7006
[root@server1 cluster]# cd 7001
[root@server1 7001]# vim redis.conf
[root@server1 7001]# cd ..
[root@server1 cluster]# ls
7001  7002  7003  7004  7005  7006

在文件夹 7000 至 7005 中, 各创建一个 redis.conf 文件, 文件的内容可以使用上面的示例配置文件, 但记得将配置中的端口号从 7000 改为与文件夹名字相同的号码。

从 Redis Github 页面 的 unstable 分支中取出最新的 Redis 源码, 编译出可执行文件 redis-server , 并将文件复制到 cluster 文件夹
在集群中保持一个独一无二(unique)的名字
这里写图片描述
每个节点都要启动
查看日志
可能会有以下的警告,按照所给的提示进行修改即可

[root@server1 7001]# ls
appendonly.aof  nodes.conf  redis.conf  redis.log  redis.pid
[root@server1 7001]# cat redis.log 
1525:C 11 Aug 10:04:10.273 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1525:C 11 Aug 10:04:10.273 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=1525, just started
1525:C 11 Aug 10:04:10.274 # Configuration loaded
1526:M 11 Aug 10:04:10.276 * Increased maximum number of open files to 10032 (it was originally set to 1024).
1526:M 11 Aug 10:04:10.276 * No cluster configuration found, I'm bac1de8bd276fa3f628792f6334af983426ab135
1526:M 11 Aug 10:04:10.982 * Running mode=cluster, port=7001.
1526:M 11 Aug 10:04:10.982 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1526:M 11 Aug 10:04:10.982 # Server initialized
1526:M 11 Aug 10:04:10.982 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1526:M 11 Aug 10:04:10.982 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
1526:M 11 Aug 10:04:10.982 * Ready to accept connections
[root@server1 7001]# echo 511 > /proc/sys/net/core/somaxconn
[root@server1 7001]# sysctl -w vm.overcommit_memory=1
vm.overcommit_memory = 1
[root@server1 7001]# vim /etc/sysctl.conf 
[root@server1 7001]# echo never > /sys/kernel/mm/transparent_hugepage/enabled

现在我们已经有了六个正在运行中的 Redis 实例, 接下来我们需要使用这些实例来创建集群, 并为每个节点编写配置文件。

通过使用 Redis 集群命令行工具 redis-trib , 编写节点配置文件的工作可以非常容易地完成: redis-trib 位于 Redis 源码的 src 文件夹中, 它是一个 Ruby 程序, 这个程序通过向实例发送特殊命令来完成创建新集群, 检查集群, 或者对集群进行重新分片(reshared)等工作。

这个命令在这里用于创建一个新的集群, 选项–replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。

之后跟着的其他参数则是这个集群实例的地址列表,3个master3个slave redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中,让各个节点开始互相通讯,最后可以得到如下信息:

root@server1 7001]# redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
Adding replica 127.0.0.1:7006 to 127.0.0.1:7002
Adding replica 127.0.0.1:7004 to 127.0.0.1:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: bac1de8bd276fa3f628792f6334af983426ab135 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
M: 7b27f05c574d8943455404400b5ccd7a13aeb4ea 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
M: df3a33ab5eebe048d6f28337071f849f2454d9c2 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
S: 4af16ec541d4bb88ac5e251c1a12544948681f57 127.0.0.1:7004
   replicates 7b27f05c574d8943455404400b5ccd7a13aeb4ea
S: 2adae51df95a4c9a833b52b72ec6624ee210b34b 127.0.0.1:7005
   replicates df3a33ab5eebe048d6f28337071f849f2454d9c2
S: cb6f64329d15a9af752f73f1c0efb62916969311 127.0.0.1:7006
   replicates bac1de8bd276fa3f628792f6334af983426ab135
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join..
..
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: bac1de8bd276fa3f628792f6334af983426ab135 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 4af16ec541d4bb88ac5e251c1a12544948681f57 127.0.0.1:7004
   slots: (0 slots) slave
   replicates 7b27f05c574d8943455404400b5ccd7a13aeb4ea
S: 2adae51df95a4c9a833b52b72ec6624ee210b34b 127.0.0.1:7005
   slots: (0 slots) slave
   replicates df3a33ab5eebe048d6f28337071f849f2454d9c2
M: 7b27f05c574d8943455404400b5ccd7a13aeb4ea 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: df3a33ab5eebe048d6f28337071f849f2454d9c2 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: cb6f64329d15a9af752f73f1c0efb62916969311 127.0.0.1:7006
   slots: (0 slots) slave
   replicates bac1de8bd276fa3f628792f6334af983426ab135
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
##这表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运作正常。

下面做个测试
将1 杀掉 可以看到2 已经为master 且依旧可以获取到数据
这里写图片描述
这里写图片描述

lnmp 里用redis作mysql的缓存

首先 配置一下环境
我这里使用三台机器
1:nginx。php
2:redis缓存
3:mysql数据库
1:
这里写图片描述
下载nginx以及php的相关组件

 vim /etc/php.ini

在这里把时区一改
在nginx里面

 vim /etc/nginx/conf.d/default.conf 

这里写图片描述
这里写图片描述

[root@server1 redis]# cd /usr/share/nginx/html/
[root@server1 html]# ls
50x.html  index.html  index.php

在这里面
下一个页面测试一下
接下来可以使用php语言编写的调用数据库

<?php
        $redis = new Redis();
        $redis->connect('172.25.19.2',6379) or die ("could net connect redis server");
  #      $query = "select * from test limit 9";
        $query = "select * from test";
        for ($key = 1; $key < 10; $key++)
        {
                if (!$redis->get($key))
                {
                        $connect = mysql_connect('172.25.19.3','redis','westos');
                        mysql_select_db(test);
                        $result = mysql_query($query);
                        //如果没有找到$key,就将该查询sql的结果缓存到redis
                        while ($row = mysql_fetch_assoc($result))
                        {
                                $redis->set($row['id'],$row['name']);
                        }
                        $myserver = 'mysql';
                        break;
                }
                else
                {
                        $myserver = "redis";
                        $data[$key] = $redis->get($key);
                }
        }

        echo $myserver;
        echo "<br>";
        for ($key = 1; $key < 10; $key++)
        {
                echo "number is <b><font color=#FF0000>$key</font></b>";

                echo "<br>";

                echo "name is <b><font color=#FF0000>$data[$key]</font></b>";

                echo "<br>";
        }
?>

写到index.html
这里面写道先去看redis缓存
然后曲调用数据库
但是这里面并没有redis这个模块
所以我们要加入

[root@server1 html]# php -m
[PHP Modules]
bz2
calendar
Core
ctype
curl
date
ereg
exif
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
json
libxml
mbstring
mysql
mysqli
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
readline
Reflection
session
shmop
SimpleXML
sockets
SPL
sqlite3
standard
tokenizer
xml
zip
zlib
[root@server1 redis]# unzip phpredis-master.zip 
[root@server1 redis]# cd phpredis-master
[root@server1 phpredis-master]# 
[root@server1 phpredis-master]# ls
common.h   debian.control  mkdeb-apache2.sh  redis_session.c
config.m4  igbinary        php_redis.h       redis_session.h
CREDITS    library.c       README.markdown   serialize.list
debian     library.h       redis.c           tests
[root@server1 phpredis-master]# php
php         php-cgi     php-config  php-fpm     phpize
[root@server1 phpredis-master]# phpize 
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626
[root@server1 phpredis-master]# LS
-bash: LS: command not found
[root@server1 phpredis-master]# ls
acinclude.m4    config.sub      library.c         README.markdown
aclocal.m4      configure       library.h         redis.c
autom4te.cache  configure.in    ltmain.sh         redis_session.c
build           CREDITS         Makefile.global   redis_session.h
common.h        debian          missing           run-tests.php
config.guess    debian.control  mkdeb-apache2.sh  serialize.list
config.h.in     igbinary        mkinstalldirs     tests
config.m4       install-sh      php_redis.h
[root@server1 phpredis-master]# ./configure 
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
checking for cc... cc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether cc accepts -g... yes
checking for cc option to accept ISO C89... none needed
checking how to run the C preprocessor... cc -E
checking for icc... no
checking for suncc... no
checking whether cc understands -c and -o together... yes
checking for system library directory... lib
checking if compiler supports -R... no
checking if compiler supports -Wl,-rpath,... yes
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for PHP prefix... /usr
checking for PHP includes... -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib
checking for PHP extension directory... /usr/lib64/php/modules
checking for PHP installed headers prefix... /usr/include/php
checking if debug is enabled... no
checking if zts is enabled... no
checking for re2c... no
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
checking for gawk... gawk
checking whether to enable redis support... yes, shared
checking for a sed that does not truncate output... (cached) /bin/sed
checking for fgrep... /bin/grep -F
checking for ld used by cc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1966080
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for ar... ar
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from cc object... ok
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if cc supports -fno-rtti -fno-exceptions... no
checking for cc option to produce PIC... -fPIC -DPIC
checking if cc PIC flag -fPIC -DPIC works... yes
checking if cc static flag -static works... no
checking if cc supports -c -o file.o... yes
checking if cc supports -c -o file.o... (cached) yes
checking whether the cc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
configure: creating ./config.status
config.status: creating config.h
config.status: executing libtool commands
[root@server1 phpredis-master]# make && make install
完成之后
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# ls
curl.ini      json.ini      mysql.ini      pdo_sqlite.ini  zip.ini
fileinfo.ini  mbstring.ini  pdo.ini        phar.ini
gd.ini        mysqli.ini    pdo_mysql.ini  sqlite3.ini
[root@server1 php.d]# cp mysql.ini redis.ini
[root@server1 php.d]# vim redis.ini 
[root@server1 php.d]# 
[root@server1 php.d]# vim redis.ini 
>extension=redis.so

当然redis端必须时master的状态
再次查看

[root@server1 php.d]# php -m | grep redis
redis

在数据库端写入一些数据
这里写图片描述
通过网页访问
这里写图片描述
到这里,我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis
中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情
况。所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。
配置 gearman 实现数据同步
Gearman 是一个支持分布式的任务分发框架:
Gearman Job Server: Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。
Gearman Client:可以理解为任务的请求者。
Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式
运行,Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。
大致流程:下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。修改表,插入表就相当于直接
下发任务。然后通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式,然后
在通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中,最后通过
redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新。

1. 安装 gearman 软件包:
gearmand libgearman-devel libgearman libevent libevent-devel
libevent-doc libevent-headers tokyocabinet
# service gearmand start
#启动服务
# netstat -antlp |grep gearmand
tcp
0
0 0.0.0.0:4730
7304/gearmand
0.0.0.0:*
LISTEN
2. 安装 php 的 gearman 扩展
https://pecl.php.net
yum install -y db*-devel
tar zxf gearman-1.1.2.tgz
cd gearman-1.1.2
./configure --with-php-config=/usr/bin/php-config
make && make install
# vim /etc/php.ini
extension=gearman.so
# service php-fpm reload
3. 安装 lib_mysqludf_json
lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映
射为 JSON 格式,是通过程序来转换的。
https://github.com/mysqludf/lib_mysqludf_json
# yum install -y mysql-devel# 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

在server3中:

查看 mysql 的模块目录:
mysql> show global variables like 'plugin_dir';
+---------------+-------------------------+
| Variable_name | Value
|
+---------------+-------------------------+
| plugin_dir
| /usr/lib64/mysql/plugin |
+---------------+-------------------------+
拷贝 lib_mysqludf_json.so 模块:
# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
注册 UDF 函数
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME
'lib_mysqludf_json.so';
查看函数
mysql> select * from mysql.func;
+--------------------+-----+-------------------------+----------+
| name
| ret | dl
| type
|
+--------------------+-----+-------------------------+----------+
| json_object
| 0 | lib_mysqludf_json.so | function |
+--------------------+-----+-------------------------+----------+
4. 安装 gearman-mysql-udf
这个插件是用来管理调用 Gearman 的分布式的队列。
https://launchpad.net/gearman-mysql-udf
# tar zxf gearman-mysql-udf-0.6.tar.gz
# cd gearman-mysql-udf-0.6
# ./configure --with-mysql=/usr/bin/mysql_config
--libdir=/usr/lib64/mysql/plugin/
# make# make install
注册 UDF 函数
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME
'libgearman_mysql_udf.so';
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME
'libgearman_mysql_udf.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 |
+--------------------+-----+-------------------------+----------+
指定 gearman 的服务信息
mysql> SELECT gman_servers_set('127.0.0.1:4730');
+------------------------------------+
| gman_servers_set('127.0.0.1:4730') |
+------------------------------------+
| 127.0.0.1:4730
|
+------------------------------------+
5. 编写 mysql 触发器(根据实际情况编写)
# vim test.sql
use test;
DELIMITER $$
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> SHOW TRIGGERS FROM test;+-------------+--------+-------+------------------------------------------------------------------------
-------+----------------------+--------------------+
| 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 |
+-------------+--------+-------+------------------------------------------------------------------------
-------+----------------------+--------------------+

server1:

编写 gearman 的 worker 端
# vim worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.19.2', 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); #这条语句就是将 id 作 KEY 和
name 作 VALUE 分开存储,需要和前面写的 php 测试代码的存取一致。
}
?>
后台运行 worker
# nohup php worker.php &

然后更新数据
查看
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值