redis:
非关系型数据库 基于键值对的形式存储数据的
查询效率非常的高 没有表之间的约束 查询起来比较方便
redis特点:
1.支持多种数据类型
2.支持分布式存储
3.功能集比较丰富
4.开源(有很多人进行优化)
缓存:
缓存静态数据(squid varnish(提高用户的访问速度))
对于动态数据而言,所有的请求都在数据库上(主从) 从而减轻数据库压力
为了让数据库能够更好的减轻压力,使用redis作为缓存 ,缓存动态数据
怎么缓存动态数据(读写分离)
写入数据的时候写入mysql 读取数据在redis上 如果客户端的请求,在redis上未命中,则去后端进行查询,并由后端反馈给客户端,在反馈同时也会给redis发送一份,从而让redis进行缓存,缓存时缓存的是key value,客户端查询key(select 。。。)结果value。
redis支持比较小的数据
有周期性的 需要设置时间
redis先将数据缓存在内存中,可以通过周期,把缓存在内存中内容通过AOF和RDB的形式写入到硬盘当中(数据不会丢失)需要更新
redis中缓存的数据:
1.不会经常修改的数据 用户信息 商品的简介 商品的分类
2.查询比较高效率的 也要存放在里面 提高用户访问的速度
什么时候不太适合用缓存? 需要和数据库强一致性
redis的遇到的问题
redis出现穿透:
当请求是不正常的请求,redis查询不到对应的数据,直接去数据库上去请求,会让数据库不太安全
去查找解决方式
1.拒绝连接
redis出现雪崩:
当请求量过于大,redis查询的时间长,积压了很多请求,redis宕机,对于redis所有的请求全部到了mysql。
2.设置当前的最大连接
redis的常用命令:
select 切换数据库 redis默认有16个数据库 (0-15)
set 创建键值对 对于键值对存在这种情况 会直接覆盖
set key value
get 查看指定的键值对
get key
mset 批量创建键值对
mset key1 value key2 value
append 对指定的键的值的内容进行追加
apppend key append value
keys* 查看所有数据库的键
dbsize 统计数据库键的个数
move 对键值对进行迁移
move key db
del 删除指定的键值对 可以是多个
del key1 key2
flushall 清除数据库中所有的键值对
redis缓存LNMP
需要具备一体化LNMP一台,在此基础上进行操作
主机 | ip |
---|---|
redis | 192.168.10.20 |
[root@localhost ~]# vim /usr/local/php/etc/php-fpm.conf
151 listen = 192.168.10.20:9000
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
67 fastcgi_pass 192.168.10.20:9000;
[root@localhost ~]# killall -9 nginx
[root@localhost ~]# nginx
[root@localhost ~]# systemctl restart php-fpm
安装redis服务
[root@localhost ~]# tar -zxf redis-4.0.6.tar.gz -C /usr/src/
[root@localhost ~]# mv /usr/src/redis-4.0.6/ /usr/local/redis
[root@localhost ~]# cd /usr/local/redis/
[root@localhost redis]# make && make install
[root@localhost redis]# vim redis.conf
69 bind 192.168.10.20 #本机的ip
136 daemonize yes
[root@localhost redis]# redis-server /usr/local/redis/redis.conf #启用redis服务
76430:C 04 Dec 15:11:47.527 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
76430:C 04 Dec 15:11:47.527 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=76430, just started
[root@localhost redis]# netstat -anput | grep redis
tcp 0 0 192.168.10.20:6379 0.0.0.0:* LISTEN 76431/redis-server
[root@localhost redis]# redis-cli -h 192.168.10.20 -p 6379 #登入redis数据库
192.168.10.10:6379> SELECT 0 #切换数据库,默认有16个数据库(0-15)
OK
以下为一些常用命令的演示:
192.168.10.20:6379> SET name one
OK
192.168.10.20:6379> GET name
"one"
192.168.10.20:6379> keys *
1) "name"
192.168.10.20:6379> dbsize
(integer) 1
192.168.10.20:6379> MSET test rr test1 tt
OK
192.168.10.20:6379> DBSIZE
(integer) 3
192.168.10.20:6379> MOVE name 2
(integer) 1
192.168.10.20:6379> DBSIZE
(integer) 2
192.168.10.20:6379> FLUSHALL #清除数据库中所有的键值对
OK
lnmp上打redis模块
[root@localhost ~]# unzip phpredis-master.zip
[root@localhost ~]# cd phpredis-master/
[root@localhost phpredis-master]# ls
common.h debian library.c php_redis.h redis_session.c tests
config.m4 debian.control library.h README.markdown redis_session.h
CREDITS igbinary mkdeb-apache2.sh redis.c serialize.list
[root@localhost phpredis-master]# ln -s /usr/local/php/bin/* /usr/local/bin/
[root@localhost phpredis-master]# ln -s /usr/local/php/sbin/* /usr/local/sbin/
[root@localhost phpredis-master]# phpize #如果这里执行不成功 如果报错 需要安装依赖关系autoconf
Configuring for:
PHP Api Version: 20170718
Zend Module Api No: 20170718
Zend Extension Api No: 320170718
[root@localhost phpredis-master]# ./configure --with-php-cOnfig=/usr/local/php/bin/php-config && make && make install
[root@localhost phpredis-master]# cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
[root@localhost no-debug-non-zts-20090626]# ls
redis.so
[root@localhost no-debug-non-zts-20090626]# vim /usr/local/php/php.ini
#最后一行添加
extension = redis.so
[root@localhost no-debug-non-zts-20090626]# systemctl restart php-fpm
[root@localhost no-debug-non-zts-20090626]# firefox 192.168.10.20/index.php #redis模块应该是打入到PHP中了
[root@localhost ~]# mysql -uroot -p
mysql> create database abc;
mysql> use abc;
mysql> create table test(id int,name varchar(10));
mysql> insert into test values(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five");
mysql> select * from test;
mysql> grant all on abc.test to "root"@"192.168.10.20" identified by "123.com";
mysql> flush privileges;
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# vim index.php
$redis=new Redis;
$redis->connect("192.168.10.20",6379) or die ("could not connect"); #redis连接的ip
$query="select * from abc.test limit 5"; #查询限制到5
for ($key=1;$key<=5;$key++) {
if (!$redis->get($key)) { #如果没有在redis获取到值
$cOnn=mysql_connect("192.168.10.20","root","123.com"); #就直接连接数据库
$result=mysql_query($query); #结果直接输出
while ($row=mysql_fetch_assoc($result)) {
$redis->set($row["id"],$row["name"]); #并且缓存在redis当中
}
break; #正常结束
}
else {
$name="redis";
$data[$key]=$redis->get($key); #将redis的值直接输出
}
}
echo $name; #redis输出格式
echo "
";
for ($key=1;$key<=5;$key++) {
echo "id is $key";
echo "
";
echo "name is $data[$key]";
echo "
";
}
?>
[root@localhost html]# firefox 192.168.10.20/index.php
[root@localhost html]# redis-cli -h 192.168.10.20 -p 6379
192.168.10.20:6379> keys *
1) "5"
2) "4"
3) "2"
4) "3"
5) "1"
redis可以做分布式存储 集群
也就是在一台主机不够mysql缓存 可以使用多台组合在一起,形成一个集群,以便于更好的存储
redis的集群 最少需要3个节点 3个节点为了其安全 还需要3个备份
每个节点之间的地位都是平等的 每个上面都有连接
redis集群的原理:
redis是通过hash槽点来进行分配数据的
redis总共有16384个槽点(0-16383)
将这些槽点平均的分配到每台主节点上,只有有槽点的主节点才会进行工作,主节点上有槽点,从节点上没有槽点,当主节点宕机,那么槽点会迁移,迁移到从节点上,从节点就变为主节点。当主修好添加添加回集群,就变成从节点 (槽点在哪里,数据就在哪里)
数据算法 crc16(key) % 16383 = 100(将会储存到第一个主节点)
第一个redis主节点 (0-5461)
缓存流程:
客户端发送请求(key),redis(集群)crc16算法,当前这个请求的数据会在那一台主机上,假如是第一个主节点,如果第一个主节点上有匹配到的数据 则直接返回,如果没有,则将请求交给后端mysql,mysql直接给客户端回应,在给客户端回应的同时,会将数据发送给redis第一个主机点一份,主节点进行保存,这样这个key就会有一个value,等到下一个客户端如果有一样请求,就会直接返回
redis如果使用多台主机做集群
需要注意,将从节点不要和其主机点放在一台主机上,这样会造成,如果整个物理机坏掉,那么数据也会丢失,交叉排放就是为了当其中一个物理机坏掉时,整个数据都还存在
实验:
为了方便起见我们通过多开端口 来启动6个redis
一台主机启动6个节点,3个主节点,3个从节点
安装redis(上面写过具体操作就不再写了)
[root@localhost ~]# killall -9 redis-server #如果前面启用过redis则先killall杀死一下,如果没有则忽略这条命令
[root@localhost ~]# mkdir /usr/local/cluster
[root@localhost ~]# cd /usr/local/cluster/
[root@localhost cluster]# mkdir {7000..7005}
[root@localhost cluster]# cp /usr/local/redis/redis.conf 700
[root@localhost cluster]# cp /usr/local/redis/redis.conf 7000/
[root@localhost cluster]# vim 7000/redis.conf
69 bind 192.168.10.20 #监听的ip
92 port 7000 #端口
136 daemonize yes #后台运行
672 appendonly yes #开启aof持久化
676 appendfilename "appendonly-7000.aof" ##aof持久化生成的文件名
814 cluster-enabled yes #开启集群功能
822 cluster-config-file nodes-7000.conf ##集群节点的配置文件
828 cluster-node-timeout 5000 #集群节点之间连接超时的时间
[root@localhost cluster]# cp 7000/redis.conf 7001/
[root@localhost cluster]# cp 7000/redis.conf 7002/
[root@localhost cluster]# cp 7000/redis.conf 7003/
[root@localhost cluster]# cp 7000/redis.conf 7004/
[root@localhost cluster]# cp 7000/redis.conf 7005/
[root@localhost cluster]# sed -i "s/7000/7001/g" 7001/redis.conf
[root@localhost cluster]# cat 7001/redis.conf | grep 7001
port 7001
appendfilename "appendonly-7001.aof"
cluster-config-file nodes-7001.conf
[root@localhost cluster]# cat 7002/redis.conf | grep 7002
port 7002
appendfilename "appendonly-7002.aof"
cluster-config-file nodes-7002.conf
[root@localhost cluster]# sed -i "s/7000/7003/g" 7003/redis.conf
[root@localhost cluster]# cat 7003/redis.conf | grep 7003
port 7003
appendfilename "appendonly-7003.aof"
cluster-config-file nodes-7003.conf
[root@localhost cluster]# sed -i "s/7000/7004/g" 7004/redis.conf
[root@localhost cluster]# cat 7004/redis.conf | grep 7004
port 7004
appendfilename "appendonly-7004.aof"
cluster-config-file nodes-7004.conf
[root@localhost cluster]# sed -i "s/7000/7005/g" 7005/redis.conf
[root@localhost cluster]# cat 7005/redis.conf | grep 7005
port 7005
appendfilename "appendonly-7005.aof"
cluster-config-file nodes-7005.conf
#启动
[root@localhost cluster]# redis-server 7000/redis.conf
[root@localhost cluster]# redis-server 7001/redis.conf
[root@localhost cluster]# redis-server 7002/redis.conf
[root@localhost cluster]# redis-server 7003/redis.conf
[root@localhost cluster]# redis-server 7004/redis.conf
[root@localhost cluster]# redis-server 7005/redis.conf
[root@localhost cluster]# netstat -anput | grep redis-server
tcp 0 0 192.168.10.20:17002 0.0.0.0:* LISTEN 82477/redis-server
tcp 0 0 192.168.10.20:17003 0.0.0.0:* LISTEN 82482/redis-server
tcp 0 0 192.168.10.20:17004 0.0.0.0:* LISTEN 82487/redis-server
tcp 0 0 192.168.10.20:17005 0.0.0.0:* LISTEN 82492/redis-server
tcp 0 0 192.168.10.20:7000 0.0.0.0:* LISTEN 82467/redis-server
tcp 0 0 192.168.10.20:7001 0.0.0.0:* LISTEN 82472/redis-server
tcp 0 0 192.168.10.20:7002 0.0.0.0:* LISTEN 82477/redis-server
tcp 0 0 192.168.10.20:7003 0.0.0.0:* LISTEN 82482/redis-server
tcp 0 0 192.168.10.20:7004 0.0.0.0:* LISTEN 82487/redis-server
tcp 0 0 192.168.10.20:7005 0.0.0.0:* LISTEN 82492/redis-server
tcp 0 0 192.168.10.20:17000 0.0.0.0:* LISTEN 82467/redis-server
tcp 0 0 192.168.10.20:17001 0.0.0.0:* LISTEN 82472/redis-server
[root@localhost ~]# yum -y install ruby
[root@localhost ~]# gem install redis-3.3.0.gem
Successfully installed redis-3.3.0
Parsing documentation for redis-3.3.0
Installing ri documentation for redis-3.3.0
1 gem installed
[root@localhost ~]# ln -s /usr/local/redis/src/redis-trib.rb /usr/bin/
[root@localhost ~]# redis-trib.rb create --replicas 1 192.168.10.20:7000 192.168.10.20:7001 192.168.10.20:7002 192.168.10.20:7003 192.168.10.20:7004 192.168.10.20:7005
…………
M: 37e6e0038f68fd32565cde5cdd1f533ac2c6255e 192.168.10.20:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 3361632b615353f40116c171c958f9c5d03df25d 192.168.10.20:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: dec4af2591dc170d4dbf329b4ad356b9e69619f9 192.168.10.20:7004
slots: (0 slots) slave
replicates bf5734ff714af1ff5c3fb0cbe32a97c0aa141a87
S: eac7000946dcbe453af7792078625ce301a681a7 192.168.10.20:7005
slots: (0 slots) slave
replicates 3361632b615353f40116c171c958f9c5d03df25d
S: 6c5d878b1184dc89eaf402f026645e42508496a4 192.168.10.20:7003
slots: (0 slots) slave
replicates 37e6e0038f68fd32565cde5cdd1f533ac2c6255e
M: bf5734ff714af1ff5c3fb0cbe32a97c0aa141a87 192.168.10.20:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@localhost ~]# redis-trib.rb check 192.168.10.20:7000
>>> Performing Cluster Check (using node 192.168.10.20:7000)
M: 37e6e0038f68fd32565cde5cdd1f533ac2c6255e 192.168.10.20:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 3361632b615353f40116c171c958f9c5d03df25d 192.168.10.20:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: dec4af2591dc170d4dbf329b4ad356b9e69619f9 192.168.10.20:7004
slots: (0 slots) slave
replicates bf5734ff714af1ff5c3fb0cbe32a97c0aa141a87
S: eac7000946dcbe453af7792078625ce301a681a7 192.168.10.20:7005
slots: (0 slots) slave
replicates 3361632b615353f40116c171c958f9c5d03df25d
S: 6c5d878b1184dc89eaf402f026645e42508496a4 192.168.10.20:7003
slots: (0 slots) slave
replicates 37e6e0038f68fd32565cde5cdd1f533ac2c6255e
M: bf5734ff714af1ff5c3fb0cbe32a97c0aa141a87 192.168.10.20:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@localhost ~]# redis-cli -h 192.168.10.20 -p 7000 -c #以下为测试
192.168.10.20:7000> set hbkjsdvbsdlujihsdjmvik sdgvgsdg;
-> Redirected to slot [9153] located at 192.168.10.20:7001
OK
192.168.10.20:7001> set qq aa
OK
192.168.10.20:7001>