一、redis安装
1、ubuntu在线安装
root@bogon:~# apt-get install redis-server
root@bogon:~# ps -aux|grep redis
root@bogon:~# netstat -nlt|grep 6379
root@bogon:~# /etc/init.d/redis-server status
root@bogon:~# redis-cli
127.0.0.1:6379> set a 111
OK
127.0.0.1:6379> get a
"111"
root@bogon:~# apt-get install php7.2-redis
root@bogon:~# find / -name php.ini
root@bogon:~# vim /etc/php/7.2/apache2/php.ini
添加extension=redis.so
root@bogon:~# /etc/init.d/apache2 restart 重启apache服务器
root@bogon:~# vim /etc/redis/redis.conf
requirepass 123456 取消注释,修改密码为123456
root@bogon:~# /etc/init.d/redis-server restart 重启redis服务器
2、源码包的位置一般放在 /usr/local/src 里面
安装步骤:
(1)cd /usr/local/src
(2)tar -zxvf redis-4.0.9.tar.gz
(3)cd ./redis-4.0.9
(4)(不需要编译安装,直接使用make命令)
(5)make
(6)make PREFIX=/usr/local/redis install(安装redis服务到指定目录)
(7)mkdir /etc/redis(给redis创建一个配置文件的目录,一般配置文件在/etc目录下)
(8)cp redis.conf /etc/redis/ (复制redis配置文件)
(9)cd /usr/local/redis/bin(里面有redis服务命令)
(10) ./redis-server(启动服务端,前面一定要加 ./,必须进入bin目录)
(11)(将第10步服务关闭,将redis服务改为后台运行)
(12) ./redis-server /etc/redis/redis.conf
问题点1:如何让redis服务在后台运行
解决:修改redis配置文件
vim /etc/redis/redis.conf
将daemonize no 改为daemonize yes
问题点2:如何查看redis服务开启成功
解决:(1)使用ps命令 :ps axu | grep redis-server
(2)使用netstat命令: netstat -tunple | grep 6379
问题点3:如何关闭后台的redis服务
解决:使用pkill命令: pkill -9 redis-server
使用客户端连接 ./redis-cli -h 192.168.. -p 6379
二、redis数据类型
1、string类型
适合最简单的k-v存储,类似于memcached的存储结构,短信验证码,配置信息等,就用这种类型来存储
(1) set和get命令
127.0.0.1:6379> set username chaoyang
OK
127.0.0.1:6379> get username
"chaoyang"
(2) incr:自增,对某个key的value值进行自增+1
127.0.0.1:6379> set age 23
OK
127.0.0.1:6379> get age
"23"
127.0.0.1:6379> incr age
(integer) 24
127.0.0.1:6379> get age
"24"
(3) decr:自减,对某个key的value进行自减1
127.0.0.1:6379> get age
"24"
127.0.0.1:6379> decr age
(integer) 23
127.0.0.1:6379> get age
"23"
(4) incrby:指定自增的数字 (age+5)
127.0.0.1:6379> get age
"23"
127.0.0.1:6379> incrby age 5
(integer) 28
127.0.0.1:6379> get age
"28"
(5) decrby:指定自减数字 (age-8)
127.0.0.1:6379> get age
"28"
127.0.0.1:6379> decrby age 8
(integer) 20
127.0.0.1:6379> get age
"20"
(6) keys:获取所有的key
127.0.0.1:6379> keys *
"age"
"name"
"username"
问题点1:redis的key一般是怎么设计的?有一张数据表,怎么把表的数据存到redis中?
有一张数据库表it_user,主键是id
id | username | age |
---|---|---|
1 | Tom | 36 |
2 | Mark | 45 |
解决:
①把表名作为key的前缀(it_user)
②把表的主键字段放在①中前缀的后面,一般用冒号分割(it_user:id)
③对应记录的主键值作为key的第三部分(it_user:id :1)
④把mysql的其他字段名作为第4部分(it_user:id :1:username、it_user:id :1:age)
⑤把表里的数据存到redis里
127.0.0.1:6379>set it_user:id :1:username Tom
127.0.0.1:6379> set it_user:id :1:age 36
127.0.0.1:6379> set it_user:id :2:username Mark
127.0.0.1:6379> set it_user:id :2:age 45
⑥获取用户id为1的所有的字段信息
127.0.0.1:6379> keys it_user :id:1:*
2、hash类型
一般key为ID或者唯一标示,value对应的就是详情了。如商品详情,个人信息详情,新闻详情等
hash类型类似于php的关联数组,形成这样的数组
$userInfo=array('name'=>'asion','age'=>12,'email'=>'asion@163.com','hobby'=>'sing');
(1) hset命令:设置单个值
127.0.0.1:6379> hset userInfo age 12
(integer) 1
(2) hget命令:获取单个值
127.0.0.1:6379> hget userInfo age
"12"
(3) hmset命令 :设置多个值
127.0.0.1:6379> hmset userInfo email asion@163.com hobby sing
OK
(4) hgetall命令 :获取hash全部的值
127.0.0.1:6379> hgetall userInfo
1) "name"
2) "asion"
3) "age"
4) "12"
5) "email"
6) "asion@163.com"
7) "hobby"
8) "sing"
3、list类型
因为list是有序的,适合根据写入的时间来排序,如:最新的***,消息队列等
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)
redis的list类型被称为链表类型,链表概图如下:
(1) lpush命令:从链表的头部放入数据(A->B->C)
(2) rpush命令:从链表的尾部放入数据(C->B->A)
(3) lrange命令:返回链表中指定区间的元素,其中0表示第一个元素,1表示第二个元素,以此类推,
也可以用负数下标,-1表示列表最后一个元素,-2表示链表倒数第二个元素
(4) lpop命令:弹出链表最左侧(头部)的数据,弹出数据后,链表中就不存在该数据了
(5) rpop命令:与lpop相反,弹出链表最右侧(最后一个)的数据
问题点1:链表数据结构应用于哪些实际项目
例如:统计最近登录的10个用户
(1)如果使用mysql统计,则sql如下:select * from user order by logintime desc limit 10;
(2)换成redis实现:创建一个list类型,从链表最左侧添加新登录的用户主键ID,如果链表中的单元超过10个,只需要把最右侧的单元弹出即可
4、set类型:无序集合
可以简单的理解为ID-List的模式,如微博中一个人有哪些好友,set最牛的地方在于,可以对两个set提供交集、并集、差集操作。例
如:查找两个人共同的好友等
redis的set类型被成为集合类型
set集合满足三个特点:①无序性:集合里面的数据是没有顺序的
②唯一性:集合里面的数据是唯一性,不可重复的
③确定性:集合里面的个数是确定的
set集合概图:
集合常见运算:
①交集(A∩B):集合公共的部分,集合A和集合B的交集是2
②并集(A∪B):集合全部的部分,集合A和集合B的并集是1 2 3
③差集(A-B):A-B在集合A里面出现,但不能再集合B里面出现,集合A-集合B的结果是 1
(1) sadd:向集合里面添加元素
(2) smembers:获取集合的元素
(3) srem:移除集合中一个或多个元素
(4)spop:随机弹出某一个元素
集合的实际使用场景:一般redis的集合用于社交类型的网站里面做好友关系的展示
例如实现好友的推荐、共同好友…
案例:
①设计四个用户
②设计好友的集合
用户id为3的好友为1 、2
用户id为45的好友为2、3
③求取好友关系
获取3号和45号的共同好友(求交集) sinter
获取3号和45号的全部好友(求并集) sunion
3号给45号推荐好友(求差集) sdiff
5、zset类型:有序集合
比较适合类似于top 10等不根据插入的时间来排序的数据
zset 和 set 一样也是string类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个double类型的分数。redis正是通过分数(即上面说的权重)来为集合中的成员进行从小到大的排序。
有序集合特点:①有序性 ②唯一性 ③确定性
有序集合概图:
(1)zadd命令:添加集合元素,如果元素存在则更新对应的权重
(2)zrange命令:获取集合元素
(3)zscore命令:命令返回有序集中成员的分数值(自己理解是返回成员的权重信息)
三、php操作redis
1、php操作redis
<?php
$redis=new redis();
$host="127.0.0.1";
$port="6379";
$redis->connect($host,$port);
$redis->set('linux','linux testing');
$data=$redis->get('linux');
echo $data;
?>
结果:linux testing
2、redis的安全问题
redis操作的时候,默认不需要客户端提供认证信息,不需要密码即可对redis进行操作,本身是很危险的,所以有必要开启redis的认证功能
修改redis.conf文件
[root@iz2ze3b608hhazmstr89iqz bin]# vim /etc/redis/redis.conf
requirepass admin88 【找到这一句并修改】
重启redis服务
[root@iz2ze3b608hhazmstr89iqz bin]# pkill -9 redis-server
[root@iz2ze3b608hhazmstr89iqz bin]# cd /usr/local/redis/bin
[root@iz2ze3b608hhazmstr89iqz bin]# ./redis-server /etc/redis/redis.conf
[root@iz2ze3b608hhazmstr89iqz bin]# ./redis-cli
127.0.0.1:6379> set test testdata 结果如下图,没有权限
解决办法:(1)127.0.0.1:6379>auth admin88 【客户端连接成功后,再执行这一步输入密码】
(2)[root@iz2ze3b608hhazmstr89iqz bin]# ./redis-cli -h 127.0.0.1 -p 6379 -a admin88 【客户端连接的时候输入密码】
3、redis的持久化
(1)简介
redis为了本身数据的安全和完整性,会把内存中的数据按照一定的方法同步到电脑的硬盘中 ,这个过程被成为持久化操作。
下次再启动redis服务的时候,会把磁盘上面保存的数据重新加载到内存中
常见的持久化操作:
a.基于快照的持久化操作:
redis会按照一定的周期把内存里的数据同步到磁盘文件里面
b.基于日志文件的追加:
redis会把redis数据造成更改的命令记录到日志文件里面,然后在一次重启的时候,执行一下日志文件里面对redis写的操作,达到
数据的还原
(2)基于快照的持久化操作
[root@iz2ze3b608hhazmstr89iqz bin]# vim /etc/redis/redis.conf
save 900 1:如果在900秒之内对redis的key进行过1次操作,则会把内存里的数据同步到磁盘文件
save 300 10:如果在300秒之内对redis的key进行过10次操作,则会把内存里的数据同步到磁盘文件
save 60 10000:如果在60秒之内对redis的key进行过10000次操作,则会把内存里的数据同步到磁盘文件
①保存到哪个磁盘文件?在哪个目录?如下图:
dbfilename dump.rdb :基于快照持久化保存的文件名称
dir ./ :保存的目录,默认是相对于启动文件 redis-server的位置
②测试一下
(3)基于日志文件的追加
vim /etc/redis/redis.conf
appendonly yes :开启基于文件的持久化操作
appendonly.aof :文件的名称
备份文件的周期:
appendfsync always:代表只要存在对redis数据造成更改的操作,都要记录到磁盘文件
appendfsync everysec:代表每一秒中把对redis数据造成更改的操作都记录到磁盘文件
appendfsync no:完全交给操作系统来完成,意思是操作系统不繁忙的时候会把对redis进行数据造成更改的操作都记录到磁 盘文件上,这种操作最不可靠
测试一下:
四、其他
<?php
$redis = new Redis();
$redis->connect('127.0.0.1',6379,1);//短链接,本地host,端口为6379,超过1秒放弃链接
$redis->pconnect('127.0.0.1',6379,1);//长链接,本地host,端口为6379,超过1秒放弃链接
$redis->auth('password');//redis设置密码后,用于验证登录密码,返回【true | false】
$redis->select(0);//选择redis库,0~15 共16个库
$redis->close();//释放资源
$redis->ping(); //服务器运行正常,返回pong
$redis->ttl('key');//返回剩余过期时间[-1 | timestamps]
$redis->persist('key');//移除key的过期时间,使其永久有效,成功返回1
$redis->sort('key',[$array]);//返回或保存给定列表、集合、有序集合key中经过排序的元素,$array为参数limit等!【配合$array很强大】 [array|false]
/*2.共性的运算归类*/
$redis->expire('key',10);//设置失效时间[true | false]
$redis->move('key',15);//把当前库中的key移动到15库中[0|1]
/*3.Server*/
$redis->dbSize();//返回当前库中的key的个数
$redis->flushAll();//清空整个redis[总true]
$redis->flushDB();//清空当前redis库[总true]
$redis->save();//同步??把数据存储到磁盘-dump.rdb[true]
$redis->bgsave();//异步??把数据存储到磁盘-dump.rdb[true]
$redis->info();//查询当前redis的状态 [verson:2.4.5....]
$redis->lastSave();//上次存储时间key的时间[timestamp]
$redis->watch('key','keyn');//监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断 [true]
$redis->unwatch('key','keyn');//取消监视一个(或多个) key [true]
$redis->multi(Redis::MULTI)