• Redis和Memcached相似,也属于k-v数据存储php
• Redis官网redis.io, 当前最新稳定版4.0.1html
• Redis是一个开源的使用ANSI C语言编写、遵照BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。mysql
它一般被称为数据结构服务器,由于值(value)能够是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。linux
•支持更多value类型,除了和string外,还支持hash、lists(链表)、sets(集合)和sorted sets(有序集合)git
• 经常使用存储类型 : string、hash、lists(链表)、sets(集合)、sorted sets(有序集合)github
• redis使用了两种文件格式:全量数据(RDB)和增量请求(aof)。全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载。增量请求文件则是把内存中的数据序列化为操做请求,用于读取文件进行replay获得数据,这种相似于mysql binlog。全量数据搞过一次以后,全量数据能够删除掉。面试
• redis的存储分为内存存储、磁盘存储和log文件三部分 redis
• 下载最新稳定版sql
• cd /usr/local/src/数据库
• wget http://download.redis.io/releases/redis-4.0.1.tar.gz
• cd redis-4.0.1
• make && make install
• cp redis.conf /etc/redis.conf
• vim /etc/redis.conf //修改以下配置
daemonize yes
logfile "/var/log/redis.log"
dir /data/redis_data/
appendonly yes
• mkdir /data/redis_data
• sysctl vm.overcommit_memory=1
• echo never > /sys/kernel/mm/transparent_hugepage/enabled
• redis-server /etc/redis.conf
实例:
[root@localhost 0]# cd /usr/local/src/ [root@localhost src]# wget http://download.redis.io/releases/redis-4.0.1.tar.gz [root@localhost src]# tar zxvf redis-4.0.1.tar.gz [root@localhost src]# cd redis-4.0.1 编译 [root@localhost redis-4.0.1]# make && make install [root@localhost redis-4.0.1]# echo $? #检测上一步是否正确 0 测试redis是否正常运行 [root@localhost 01]# redis- #敲两次回车,自动查看相关命令 redis-benchmark redis-check-rdb redis-sentinel redis-check-aof redis-cli redis-server [root@localhost 01]# which redis-cli #查看安装位置 /usr/local/bin/redis-cli 把配置文件拷贝到/etc/redis.conf文件下 [root@localhost 01]# cp redis.conf /etc/redis.conf [root@localhost 01]# vim /etc/redis.conf 把daemonize no设置成daemonize yes #该成yes以后,就在后台启动 把日志的文件logfile “”修改为logfile "/var/log/redis.log" #指定日志文件 把dir ./ 修改为dir /data/redis # dir是指定dump文件的位置 appendonly no 修改为 appendonly yes #做用开启ouf日志,开启后,会在dir指定的目录中生成appendfilename aof文件 建立一个新的文件 [root@localhost 01]# mkdir /data/redis [root@localhost 0]# redis-server /etc/redis.conf #启动redis服务 [root@localhost 01]# ps aux |grep redis root 88045 0.1 0.2 145296 2192 ? Ssl 15:56 0:00 redis-server 127.0.0.1:6379 root 88059 0.0 0.0 112720 968 pts/0 R+ 15:57 0:00 grep --color=auto redis [root@localhost 01]# less /var/log/redis.log #查看日志 [root@localhost 01]# sysctl vm.overcommit_memory=1 vm.overcommit_memory = 1 [root@localhost 01]# echo never > /sys/kernel/mm/transparent_hugepage/enabled [root@localhost 01]# vim /etc/rc.local touch /var/lock/subsys/local #下面是添加的内容 sysctl vm.overcommit_memory=1 echo never > /sys/kernel/mm/transparent_hugepage/enabled
• Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)
• RDB,简而言之,就是在不一样的时间点,将redis存储的数据生成快照并存储到磁盘等介质上。若是存储到内存中,重启以后就会数据就会消失。
• AOF,则是换了一个角度来实现持久化,那就是将redis执行过的全部写指令记录下来,在下次redis从新启动时,只要把这些写指令从前到后再重复执行一遍,就能够实现数据恢复了。
• 其实RDB和AOF两种方式也能够同时使用,在这种状况下,若是redis重启的话,则会优先采用AOF方式来进行数据恢复,这是由于AOF方式的数据恢复完整度更高。数据和日志会先存储到内存中,而后同步到磁盘中。
• 若是你没有数据持久化的需求,也彻底能够关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache同样。
save 900 1 #表示每15分钟且至少有1个key改变,就触发一次持久化
save 300 10 #表示每5分钟且至少有10个key改变,就触发一次持久化
save 60 10000 #表示每60秒至少有10000个key改变,就触发一次持久
save “” #这样能够禁用rdb持久化
appendonly yes #若是是yes,则开启aof持久化
appendfilename “appendonly.aof” # 指定aof文件名字
appendfsync everysec #指定fsync()调用模式,有三种no(不调用fsync),always(每次写都会调用fsync),everysec(每秒钟调用一次fsync)。第一种最快,第二种数据最安全,但性能会差一些,第三种为这种方案,默认为第三种。
求差集的时候须要将数据多的键值放在前面。。。不然结果是空集
set1至关于set2的子集,因此set1对set2求差集结果确定是空集
• string为最简单的类型,与Memcached同样的类型,一个key对应一个value,其支持的操做与Memcached的操做相似,它的功能更丰富。设置能够存二进制的对象。
• 示例:
# redis-cli
127.0.0.1:6379> set mykey "aminglinux.com"
OK
127.0.0.1:6379> get mykey
"aminglinux.com"
127.0.0.1:6379> mset key1 1 key2 a key3 c #同时设置多个键值
127.0.0.1:6379> mget key1 key2 key3 #同时查看多个键值
1) "1"
2) "a"
3) "c"
实例
[root@localhost 0]# redis-cli 127.0.0.1:6379> set mykey 123 100 (error) ERR syntax error 127.0.0.1:6379> set mykey "123" OK 127.0.0.1:6379> get mykey "123" 127.0.0.1:6379> MSET k1 1 k2 2 k3 a OK 127.0.0.1:6379> mget k1 mykey 1) "1" 2) "123"
• list是一个链表结构,主要功能是push、pop、获取一个范围的全部值等等。操做中key理解为链表的名字。
• 使用 list 结构,咱们能够轻松地实现最新消息排行等功能(好比新浪微博的 TimeLine )。list 的另外一个应用就是消息队列,能够利用 list 的 push操做,将任务存在 list 中,而后工做线程再用pop操做将任务取出进行执行。
• 示例:
• # redis-cli
127.0.0.1:6379> LPUSH list1 "aminglinux"
127.0.0.1:6379> LPUSH list1 "1 2 3"
127.0.0.1:6379> LPUSH list1 "aaa bbb“
127.0.0.1:6379> LRANGE list1 0 -1 #查看list的值
1) "aaa bbb"
2) "1 2 3"
3) "aminglinux“
127.0.0.1:6379> LPOP list1 #取出数值
实例:
[root@localhost 01]# redis-cli 127.0.0.1:6379> LPUSH list1 "aminglinux" 127.0.0.1:6379> LPUSH list1 "1 2 3" 127.0.0.1:6379> LPUSH list1 "aaa bbb“ 127.0.0.1:6379> LRANGE list1 0 -1 #查看list的值 1) "aaa bbb" 2) "1 2 3" 3) "aminglinux“ 127.0.0.1:6379> LPOP list1
• set是集合,和咱们数学中的集合概念类似,对集合的操做有添加删除元素,有对多个集合求交并差等操做。操做中key理解为集合的名字。好比在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。由于 Redis 很是人性化的为集合提供了求交集、并集、差集等操做,那么就能够很是方便的实现如共同关注、共同喜爱、二度好友等功能,对上面的全部集合操做,你还可使用不一样的命令选择将结果返回给客户端仍是存集到一个新的集合中。
• set示例
127.0.0.1:6379> SADD set1 a
127.0.0.1:6379> SADD set1 b
127.0.0.1:6379> SADD set1 c
127.0.0.1:6379> SADD set1 d
127.0.0.1:6379> SMEMBERS set1
1) "d"
2) "b"
3) "a"
4) "c"
127.0.0.1:6379> SREM set1 c//删除元素
127.0.0.1:6379> SADD set2 a 2 b
127.0.0.1:6379> SINTER set1 set2 //交集
127.0.0.1:6379> SUNION set1 set2 //并集
127.0.0.1:6379> SDIFF set1 set2 //差集
实例
[root@localhost 01]# redis-cli 127.0.0.1:6379> SADD set1 a (integer) 1 127.0.0.1:6379> SADD set1 b (integer) 1 127.0.0.1:6379> SADD set1 c (integer) 1 127.0.0.1:6379> SADD set1 d (integer) 1 127.0.0.1:6379> SMEMBERS set1 @#查看集合中的全部元素 1) "d" 2) "c" 3) "a" 4) "b" 127.0.0.1:6379> sadd set2 a (integer) 1 127.0.0.1:6379> sadd set2 2 (integer) 1 127.0.0.1:6379> sadd set2 3 (integer) 1 127.0.0.1:6379> sadd set2 c (integer) 1 127.0.0.1:6379> SMEMBERS set2 1) "c" 2) "2" 3) "a" 4) "3" 127.0.0.1:6379> SUNION set1 set2 #查看并值 1) "2" 2) "d" 3) "c" 4) "a" 5) "b" 6) "3" 127.0.0.1:6379> SINTER set1 set2 #查看交集 1) "c" 2) "a" 127.0.0.1:6379> SDIFF set1 set2 #求差值 1) "d" 2) "b" 127.0.0.1:6379> SREM set1 c #删除set1中c (integer) 1 127.0.0.1:6379> SMEMBERS set1 #查看是否删除成功 1) "d" 2) "a" 3) "b"
• sorted set是有序集合,它比set多了一个权重参数score,使得集合中的元素可以按 score 进行有序排列,好比一个存储全班同窗成绩的 Sorted Sets,其集合 value 能够是同窗的学号,而 score 就能够是其考试得分,这样在数据插入集合的时候,就已经进行了自然的排序。
127.0.0.1:6379> ZADD set3 12 abc
127.0.0.1:6379> ZADD set3 2 "cde 123"
127.0.0.1:6379> ZADD set3 24 "123-aaa"
127.0.0.1:6379> ZADD set3 4 "a123a"
127.0.0.1:6379> ZRANGE set3 0 -1
1) "cde 123"
2) "a123a"
3) "abc"
4) "123-aaa"
倒序
127.0.0.1:6379> ZREVRANGE set3 0 -1
1) "123-aaa"
2) "abc"
3) "a123a"
4) "cde 123"
实例:
有序排列
自然排序 127.0.0.1:6379> ZADD set3 12 abc (integer) 1 127.0.0.1:6379> ZADD set3 2 "cde 123" (integer) 1 127.0.0.1:6379> ZADD set3 24 "aming" (integer) 1 127.0.0.1:6379> ZADD set3 4 "aminglinux" (integer) 1 127.0.0.1:6379> ZADD set3 0 -1 (integer) 1 127.0.0.1:6379> ZRANGE set3 0 -1 #排列的顺序是0 ,2,4,12,24 1) "-1" 2) "cde 123" 3) "aminglinux" 4) "abc" 5) "aming" 倒序 ----- 最大的在前面, 127.0.0.1:6379> ZREVRANGE set3 0 -1 1) "aming" 2) "abc" 3) "aminglinux" 4) "cde 123" 5) "-1"
• 在 Memcached 中,咱们常常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(通常是 JSON 格式),好比用户的昵称、年龄、性别、积分等。
• 示例
127.0.0.1:6379> hset hash1 name aming #设置哈希值
127.0.0.1:6379> hget hash1 name
"aming"
127.0.0.1:6379> hset hash1 age 30
127.0.0.1:6379> hget hash1 age
"30"
127.0.0.1:6379> hgetall hash1 #获取所有的哈希值
1) "name"
2) "aming"
3) "age"
4) "30"
实例:
添加元素
127.0.0.1:6379> HSET hash1 name aming #设置哈希值 (integer) 1 127.0.0.1:6379> HSET hash1 age 30 (integer) 1 127.0.0.1:6379> HSET hash1 name (error) ERR wrong number of arguments for 'hset' command 127.0.0.1:6379> HGET hash1 name #获取部分哈希值 "aming" 127.0.0.1:6379> HGET hash1 jobs (nil) 127.0.0.1:6379> HGET hash1 job (nil) 127.0.0.1:6379> hgetall hash1 #获取所有哈希值 1) "name" 2) "aming" 3) "age" 4) "30" 127.0.0.1:6379>
• set key1 aminglinux #若是以前设置过一次KEY1,再次设置就会,覆盖
• get key1
• set key1 aming //第二次赋值会覆盖
• setnx key2 aaa //返回1 若是key2不存在直接建立key
• setnx key2 bbb //返回0,若是key2存在,返回0,不存在,返回1
• setex key3 10 1 //给key3设置过时时间为10s,值为1,若key已经存在,会覆盖新的值
• mset k1 1 k2 a k3 c
• mget k1 k3 k2
• lpush lista a //从左侧加入一个元素
• lpush lista b
• lrange lista 0 -1
• lpop lista //从左侧取出第一个元素
• rpush lista 1 //从右侧加入一个元素
• rpop lista //从右侧取出第一个元素
面试的时候,可能会问一些redis持久化、集群方面的问题。
实例:
127.0.0.1:6379> set key1 aming OK 127.0.0.1:6379> set key2 linux OK 127.0.0.1:6379> set key1 linux OK 127.0.0.1:6379> get key1 #再次设置会,覆盖aming "linux" 127.0.0.1:6379> setnx key1 aaa (integer) 0 127.0.0.1:6379> get key1 "linux" 127.0.0.1:6379> setnx key3 aaa (integer) 1 127.0.0.1:6379> get key3 "aaa" 127.0.0.1:6379> set key3 aaa ex 10 #后面的10是过时时间10秒 OK 127.0.0.1:6379> get key3 #过10秒,再次查看key3的值,发现已经不存在了 (nil) 127.0.0.1:6379> set key3 aaa ex 100 #后面的100是过时时间100秒 OK 127.0.0.1:6379> get key3 #不到过时时间,能够查看key3的值 "aaa" 127.0.0.1:6379> SETEX key3 1000 bbb # "bbb" //给key3设置过时时间为10s,值为1,若key已经存在,会覆盖新的值 OK 127.0.0.1:6379> get key3 127.0.0.1:6379> LPUSH list2 aaa (integer) 1 127.0.0.1:6379> LPUSH list2 bbb (integer) 2 127.0.0.1:6379> LPUSH list2 (error) ERR wrong number of arguments for 'lpush' command 127.0.0.1:6379> LRANGE list2 0 -1 #排列顺序是,后面设置值的放在前面 1) "-1" 2) "0" 3) "bbb" 4) "aaa" 127.0.0.1:6379> LPOP list2 #抓取的值,是后面的设置的值 "-1" 127.0.0.1:6379> LPUSH list2 ccc //从左侧加入一个元素 (integer) 4 127.0.0.1:6379> LPUSH list2 ddd (integer) 5 127.0.0.1:6379> LPUSH list2 0 -1 (integer) 7 127.0.0.1:6379> LRANGE list2 0 -1 #从最小的值排列 1) "-1" 2) "0" 3) "ddd" 4) "ccc" 5) "0" 6) "bbb" 7) "aaa" 127.0.0.1:6379> RPOP list2 #抓取列表最底下的值,值取出来以后,其余的就删除掉 "aaa"
• linsert lista before 2 3 //在2的前面插入一个元素为3
• lset lista 4 bbb //把第5个元素修改成bbb
• lindex lista 0 //查看第1个元素
• lindex lista 3 //查看第4个元素
• llen lista //查看链表中有几个元素
• sadd seta aaa //向集合seta中放入元素
• smembers seta //查看集合中的全部元素
• srem seta aaa //删除元素
• spop seta //随机取出一个元素,删除
• sdiff seta setb //求差集,以seta为标准
• sdiffstore setc seta setb //求差集而且存储,存储到了setc里
• sinter seta setb //求交集
• sinterstore setd seta setb //将交集存储setd
• sunion seta setb //求并集
• sunionstore sete seta setb //求并集并存储到sete
实例:
127.0.0.1:6379> LINSERT list2 before 1 3 (integer) -1 127.0.0.1:6379> LINSERT list2 before 0 1 (integer) 7 127.0.0.1:6379> LINSERT list2 before 2 3 (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER 2 aaa (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER ccc aaa (integer) 8 127.0.0.1:6379> LINSERT list2 AFTER aaa bbb (integer) 9 127.0.0.1:6379> LRANGE list2 0 -1 1) "-1" 2) "1" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 替换值 127.0.0.1:6379> LSET list2 1 11 #把第二个值,替换成11 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替换的值 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 127.0.0.1:6379> LSET list2 0 123 #把第一个值,替换成123 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替换的值 1) "123" 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 查看元素 127.0.0.1:6379> LINDEX list2 1 #查看list2列表里第二个值 "11" 127.0.0.1:6379> LINDEX list2 0 "123" 127.0.0.1:6379> LLEN list2 #查看list2列表里面有几个值 (integer) 9 127.0.0.1:6379> LINSERT list2 before 1 3 (integer) -1 127.0.0.1:6379> LINSERT list2 before 0 1 (integer) 7 127.0.0.1:6379> LINSERT list2 before 2 3 (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER 2 aaa (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER ccc aaa (integer) 8 127.0.0.1:6379> LINSERT list2 AFTER aaa bbb (integer) 9 127.0.0.1:6379> LRANGE list2 0 -1 1) "-1" 2) "1" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 替换值 127.0.0.1:6379> LSET list2 1 11 #把第二个值,替换成11 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替换的值 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 127.0.0.1:6379> LSET list2 0 123 #把第一个值,替换成123 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替换的值 1) "123" 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 查看元素 127.0.0.1:6379> LINDEX list2 1 #查看list2列表里第二个值 "11" 127.0.0.1:6379> LINDEX list2 0 "123" 127.0.0.1:6379> LLEN list2 #查看list2列表里面有几个值 (integer) 9 127.0.0.1:6379> LINSERT list2 before 1 3 (integer) -1 127.0.0.1:6379> LINSERT list2 before 0 1 (integer) 7 127.0.0.1:6379> LINSERT list2 before 2 3 (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER 2 aaa (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER ccc aaa (integer) 8 127.0.0.1:6379> LINSERT list2 AFTER aaa bbb (integer) 9 127.0.0.1:6379> LRANGE list2 0 -1 1) "-1" 2) "1" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 替换值 127.0.0.1:6379> LSET list2 1 11 #把第二个值,替换成11 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替换的值 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 127.0.0.1:6379> LSET list2 0 123 #把第一个值,替换成123 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替换的值 1) "123" 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 查看元素 127.0.0.1:6379> LINDEX list2 1 #查看list2列表里第二个值 "11" 127.0.0.1:6379> LINDEX list2 0 "123" 127.0.0.1:6379> LLEN list2 #查看list2列表里面有几个值 (integer) 9 集合seta中放入元素 127.0.0.1:6379> sadd seta aaa (integer) 1 127.0.0.1:6379> sadd seta bbb (integer) 1 127.0.0.1:6379> SMEMBERS seta 1) "aaa" 2) "bbb" 127.0.0.1:6379> SPOP sete #取出值,sete,就变成空的了 "bbb" 127.0.0.1:6379> SMEMBERS sete (empty list or set) 求差集,以seta为标准 127.0.0.1:6379> sadd seta aaa (integer) 0 127.0.0.1:6379> sadd seta bbb (integer) 0 127.0.0.1:6379> sadd seta cc (integer) 1 127.0.0.1:6379> sadd seta 111 (integer) 1 127.0.0.1:6379> sadd seta 222 (integer) 1 127.0.0.1:6379> sadd setb 111 (integer) 1 127.0.0.1:6379> sadd setb 222 (integer) 1 127.0.0.1:6379> SMEMBERS seta 1) "aaa" 2) "111" 3) "bbb" 4) "cc" 5) "222" 127.0.0.1:6379> SMEMBERS setb 1) "111" 2) "222" 127.0.0.1:6379> SDiFF seta setb #求差值,以第一个设置的seta为比较值,把与setb相同的值去掉 1) "aaa" 2) "bbb" 3) "cc" 127.0.0.1:6379> SDiFF setb seta #求差值,以第一个设置的setb为比较值,把与seta相同的值去掉 (empty list or set)
• sismember seta aaa //判断一个元素是否属于一个集合
• srandmember seta //随机取出一个元素,但不删除
• zadd zseta 11 123 //建立有序集合
• zrange zseta 0 -1 //显示全部元素,按顺序显示
• zrange zseta 0 -1 withscores //能够带上分值
• zrem zseta 222 //删除指定元素
• zrank zseta 222 //返回元素的索引值,索引值从0开始,按score正向排序
• zrevrank zseta 222 //同上,不一样的是,按score反序排序
• zrevrange zseta 0 -1 反序显示全部元素,并带分值
• zcard zseta //返回集合中全部元素的个数
• zcount zseta 1 10 // 返回分值范围1-10的元素个数
• zrangebyscore zseta 1 10 // 返回分值范围1-10的元素
• zremrangebyrank zseta 0 2 //删除索引范围0-2的元素,按score正向排序
• zremrangebyscore zseta 1 10 //删除分值范围1-10的元素
实例:
判断一个元素是否属于一个集合 127.0.0.1:6379> SISMEMBER seta 1 (integer) 0 127.0.0.1:6379> SISMEMBER seta 111 (integer) 1 127.0.0.1:6379> SRANDMEMBER seta 随机取出一个元素 "aaa" 127.0.0.1:6379> SRANDMEMBER seta 2 随机取出2个元素 1) "222" 2) "bbb" 127.0.0.1:6379> SMEMBERS seta #查看seta的全部元素 1) "aaa" 2) "cc" 3) "222" 4) "bbb" 5) "111" 127.0.0.1:6379> SPOP seta 提取最后一个元素 "111" 127.0.0.1:6379> SMEMBERS seta 提取最后一个元素 ,那一个元素就消失在列表里面 1) "aaa" 2) "cc" 3) "222" 4) "bbb" 127.0.0.1:6379> SPOP seta 提取最后一个元素 bbbb "bbb"
zadd zseta 11 123 //建立有序集合 127.0.0.1:6379> ZADD zseta 11 123 (integer) 1 127.0.0.1:6379> ZADD zseta 0 1ab (integer) 1 127.0.0.1:6379> ZRANGE zseta 1 -1 1) "1ab" 2) "123" 127.0.0.1:6379> ZRANGE zseta 0 -1 1) "-1" 2) "1ab" 3) "123" 删除元素,上面添加了两个元素,123,1ab 127.0.0.1:6379> ZREM zseta 1ab (integer) 1 127.0.0.1:6379> ZRANGE zseta 0 -1 #删除成功了 1) "-1" 2) "123" 元素的索引值,以前先添加几个值, 127.0.0.1:6379> ZADD zseta 10 1ab (integer) 1 127.0.0.1:6379> ZADD zseta 14 ssasb (integer) 1 127.0.0.1:6379> ZADD zseta 16 12123123 (integer) 1 127.0.0.1:6379> ZADD zseta 1000 sdasdf (integer) 1 127.0.0.1:6379> ZRANGE zseta 0 -1 1) "-1" 2) "1ab" 3) "123" 4) "ssasb" 5) "12123123" 6) "sdasdf" 127.0.0.1:6379> 返回元素的索引值,索引值从0开始,按score正向排序 127.0.0.1:6379> ZRANk zseta 1ab (integer) 1 127.0.0.1:6379> ZRANk zseta 123 (integer) 2 127.0.0.1:6379> ZRANk zseta ssasb (integer) 3 同上,不一样的是,按score反序排序 127.0.0.1:6379> ZREVRANK zseta ssasb (integer) 2 反序显示全部元素,并带分值 127.0.0.1:6379> zrevrange zseta 0 -1
• hset user1 name aming //创建hash
• hset user1 age 30
• hset user1 job it
• hgetall user1
• hmset user2 name aming age 30 job it //批量创建键值对
• hmget user2
• hmget user2 name age job
• hdel user2 job //删除指定filed
• hkeys user2 //打印全部的key
• hvals user2 //打印全部的values
• hlen user2 //查看hash有几个filed
实例:
127.0.0.1 > hset user1 name aming //创建hash OK 127.0.0.1 > HGETALL hase2 127.0.0.1 > HMGET hash2 b c #获取值 1) (nil) 2) (nil) 127.0.0.1 > hkeys user2 //打印全部的key 127.0.0.1 > hkeys user2 //打印全部的key 127.0.0.1 > hvals user2 //打印全部的values 127.0.0.1 > hlen user2 //查看hash有几个filed
• keys * //取出全部key
• keys my* //模糊匹配
• exists name //有name键 返回1 ,不然返回0;
• del key1 // 删除一个key //成功返回1 ,不然返回0;
• EXPIRE key1 100 //设置key1 100s后过时
• ttl key // 查看键 还有多长时间过时,单位是s,当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 不然,返回 key 的剩余生存时间。
• select 0 //表明选择当前数据库,默认进入0 数据库
• move age 1 // 把age 移动到1 数据库
• persist key1 //取消key1的过时时间
• randomkey //随机返回一个key
• rename oldname newname //重命名key
• type key1 //返回键的类型
注意:timeout指的是设置客户端链接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该链接。
实例:
127.0.0.1::6877> keys * //取出全部key键 127.0.0.1::6877> keys my* //模糊匹配 127.0.0.1::6877> exists key1 //有name键 返回1 ,不然返回0; 1) "mykey" 127.0.0.1:6379> exists non 返回0; (integer) 0 127.0.0.1:6379> DEL key1 (integer) 1 127.0.0.1:6379> get key1 (nil) #空 127.0.0.1::6877> EXPIRE key1 10 //设置key1 10s后过时 (integer) 0 127.0.0.1:6379> get k1 "2" 127.0.0.1:6379> get k1 (nil) 127.0.0.1:6379> EXPIRE key2 2 (integer) 1 127.0.0.1:6379> get key2 (nil) 127.0.0.1::6877> ttl key1 // 查看键 还有多长时间过时 127.0.0.1:6379> get key1 (integer)1 127.0.0.1:6379> ttl key2 (integer) -2 #已通过期两秒 127.0.0.1:6379> SELECT 1 #进入1数据库 OK 127.0.0.1::6877> keys * (empty list or set) 127.0.0.1:6379[1]> SELECT 0 # 进入0 数据库 OK 127.0.0.1:6379> keys * #查看全部的键值 1) "k2" 2) "zseta" 3) "list2" 4) "setb" 5) "k3" 6) "mykey" 7) "k1" 8) "seta" 9) "set3" 10) "list1\xc2\xa0" 11) "set2" 12) "hash1" 13) "set1" 14) "user1" 127.0.0.1:6379> move set2 1 // 把set2 移动到1 数据库 (integer) 1 127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> keys * 1) "set2" 127.0.0.1::6877> EXPIRE mykey 10 #设置过时时间 (integer)1 127.0.0.1::6877> ttl mykey (integer) 8 127.0.0.1::6877> PERSIST mykey //取消key1的过时时间 (integer)1 127.0.0.1::6877> ttl mykey (integer) -1 127.0.0.1::6877> RANDOMKEY //每次执行,随机返回一个key "set2" 127.0.0.1::6877> rename set2 set3 //重命名set3 OK 127.0.0.1::6877> keys set* #查看全部的键值 1) "set3" 127.0.0.1::6877> TYPE seta #查看数据类型 set 127.0.0.1:6379[1]> type seta none
• dbsize //返回当前数据库中key的数目
• info //返回redis数据库状态信息
• flushdb //清空当前数据库中全部的键
• flushall //清空全部数据库中的全部的key
• bgsave //保存数据到 rdb文件中,在后台运行
• save //做用同上,可是在前台运行
• config get * //获取全部配置参数
• config get dir //获取配置参数
• config set dir //更改配置参数
• 数据恢复: 首先定义或者肯定dir目录和dbfilename,而后把备份的rdb文件放到dir目录下面,重启redis服务便可恢复数据
实例:
127.0.0.1:6379[1]> DBSIZE //返回当前数据库中key的数目 (integer) 1 127.0.0.1::6877>KEYS * 1) "set3 127.0.0.1::6877> info //返回redis数据库状态信息 127.0.0.1:6379> SELECT 1 OK 127.0.0.1:6376> KEYS * 1) "set3" 127.0.0.1::6877> flushdb //清空当前数据库中全部的键 OK 127.0.0.1:6379[1]> KEYS * (empty list or set) 127.0.0.1::6877> flushall //清空全部数据库中的全部的key 127.0.0.1::6877> bgsave //保存数据到 rdb文件中,在后台运行 Background saving started 127.0.0.1::6877> save //做用同上,可是在前台运行, 127.0.0.1::6877> config get * //获取全部配置参数 127.0.0.1::6877> config get dir //获取DIR配置参数 127.0.0.1::6877> config set dir //更改配置参数 127.0.0.1:6379[1]> CONFIG set timeout 5 #设置过时时间 OK 127.0.0.1:6379[1]> CONFIG get timeout #获取过时时间 1) "timeout" 2) "5 查看数据恢复目录 127.0.0.1:6379[1]> CONFIG get dir 1) "dir" 2) "/data/redis" 127.0.0.1:6379[1]> CONFIG get dbfilename 1) "dbfilename" 2) "dump.rdb"
数据恢复:把dump.rdb放到dir目录,而后启动,
• 设置监听ip
• bind 127.0.0.1 2.2.2.2//能够是多个ip,用空格分隔
• 设置监听端口 ---修改默认端口,防止入侵
• port 16000
• 设置密码,监听内网ip或者以普通用户的身份启动
• requirepass aming>com #密码aming>com
• redis-cli -a 'aming>com'
修改配置文件
• 将config命令更名
• rename-command CONFIG aming
• 禁掉config命令
• rename-command CONFIG “”
不让你的resdis.conf给别人看怎么办?好比经过限定文件或者目录权限。
实例:
[root@localhost ~]# ls -l /data/redis/ 总用量 8 -rw-r--r-- 1 root root 2798 7月 9 10:38 appendonly.aof -rw-r--r-- 1 root root 534 7月 9 10:39 dump.rdb 查看redis启动的用户,保证安全,切换到普通用户, 设置密码 [root@localhost ~]# vim /etc/redis.conf /auth #搜索的内容 requirepass aming>com 启动redis [root@localhost ~]# systemctl restart redis Failed to restart redis.service: Unit not found. [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf #再次重启服务 登陆redis,,,若是不使用密码,登陆,执行keys *会报错 [root@localhost ~]# redis-cli -a 'aming>com' 127.0.0.1:6379> keys * #登陆成功 1) "zseta" 2) "k1" 3) "setb" 4) "k3" 5) "mykey" 6) "set1" 7) "list2" 8) "seta" 9) "set3" 10) "hash1" 11) "list1\xc2\xa0" 12) "user1" 13) "k2" 127.0.0.1:6379> • 将config命令更名 • rename-command CONFIG aming [root@localhost ~]# vim /etc/redis.conf #修改配置文件 /rename #搜索关键字,而后再下面添加 rename-command CONFIG aming [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf #从新登陆 使用密码登陆 [root@localhost ~]# redis-cli -a 'aming>com' 127.0.0.1:6379> keys * 1) "k1" 2) "k3" 3) "k2" 4) "seta" 5) "list1\xc2\xa0" 6) "set3" 7) "user1" 8) "zseta" 9) "hash1" 10) "list2" 11) "setb" 12) "mykey" 13) "set1" 127.0.0.1:6379> config get dir #直接执行命令,不行 (error) ERR unknown command 'config' 127.0.0.1:6379> aming get dir #使用用户名,能够执行命令 1) "dir" 2) "/data/redis" 禁掉config命令,把里面的aming用户去掉就好了 • rename-command CONFIG “” [root@localhost ~]# vim /etc/redis.conf #修改配置文件 /rename #搜索关键字,而后再下面添加 rename-command CONFIG "" [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf #从新登陆
• 编辑配置文件/etc/redis.conf
• 针对慢查询日志,能够设置两个参数,一个是执行时长,单位是微秒,另外一个是慢查询日志的长度。当一个新的命令被写入日志时,最老的一条会从命令日志队列中被移除。若是超过1千,好比1001,那么第一条就被移除了
• slowlog-log-slower-than 1000 / /单位ms,表示慢于1000ms则记录日志,
• slowlog-max-len 128 //定义日志长度,表示最多存128条
• slowlog get //列出全部的慢查询日志
• slowlog get 2 //只列出2条
• slowlog len //查看慢查询日志条数
•
实例:
[root@localhost 01]# vim /etc/redis.conf slowlog-log-slower-than 10 表明超过10微秒,就记录 slowlog-max-len 128 表明128条 启动redis [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf [root@localhost ~]# redis-cli -a 'aming>com' 127.0.0.1:6379> SLOWLOG get 查看记录 1) 1) (integer) 0 #由于运行一个命令,记录从0开始,0表示1条,因此显示0 2) (integer) 1531106988 3) (integer) 390 4) 1) "COMMAND" 5) "127.0.0.1:50952" 6) "" 127.0.0.1:6379> get k3 "a" 127.0.0.1:6379> get k2 "2" 127.0.0.1:6379> SLOWLOG get #又执行两条命令,以后显示三条记录 1) 1) (integer) 1 2) (integer) 1531106998 3) (integer) 18 4) 1) "SLOWLOG" 2) "get" 5) "127.0.0.1:50952" 6) "" 2) 1) (integer) 0 2) (integer) 1531106988 3) (integer) 390 4) 1) "COMMAND" 5) "127.0.0.1:50952" 6) 127.0.0.1:6379> SLOWLOG get 1 #只显示最新的一条记录,get后面的数字,表明显示的条数 1) 1) (integer) 2 2) (integer) 1531107114 3) (integer) 21 4) 1) "SLOWLOG" 2) "get" 5) "127.0.0.1:50952" 6) "" 127.0.0.1:6379> slowlog len //查看慢查询日志条数 integer) 4
php链接redis以前要安装redis扩展模块
• cd /usr/local/src
• wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip
• unzip phpredis.zip
• cd phpredis-develop
• /usr/local/php-fpm/bin/phpize
注意:有的人目录是/usr/local/php/bin/phpize,编译的时候把php-fpm换成php
• ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
• make
• make install
• vim /usr/local/php.ini //增长extension=redis.so
• /usr/local/php-fpm/bin/php -m|grep redis //看是否有redis模块
• 重启php-fpm服务
实例:
[root@localhost 01]# cd /usr/local/src [root@localhost src]# wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip [root@localhost src]# unzip phpredis.zip [root@localhost src]# cd phpredis-develop [root@localhost phpredis-develop]# /usr/local/php/bin/phpize Configuring for: PHP Api Version: 20131106 Zend Module Api No: 20131226 Zend Extension Api No: 220131226 [root@localhost phpredis-develop]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config checking for grep that handles long lines and -e... /usr/bin/grep checking for egrep... /usr/bin/grep -E checking for a sed that does not truncate output... /usr/bin/sed checking for cc... cc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no 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 configure: error: Cannot find php-config. Please use --with-php-config=PATH [root@localhost phpredis-develop]# make [root@localhost phpredis-develop]# make install Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/ [root@localhost 01]# vim /usr/local/php.ini//增长extension=redis.so #查看地下有没有redis [root@localhost phpredis-develop]# /etc/init.d/php-fpm restart #启动PHP服务 Gracefully shutting down php-fpm . done Starting php-fpm done
• vim /usr/local/php-fpm/etc/php.ini//更改或增长
session.save_handler = "redis"
session.save_path = "tcp://127.0.0.1:6379"
• 或者apache虚拟主机配置文件中也能够这样配置:
php_value session.save_handler " redis"
php_value session.save_path " tcp://127.0.0.1:6379"
• 或者php-fpm配置文件对应的pool中增长:
php_value[session.save_handler] = redis
php_value[session.save_path] = " tcp://127.0.0.1:6379 "
• wget http://study.lishiming.net/.mem_se.txt
• mv .mem_se.txt /usr/local/apache2/htdocs/session.php
• 其中session.php内容能够参考https://coding.net/u/aminglinux/p/yuanke_centos7/git/blob/master/21NOSQL/session.php
• curl localhost/session.php //结果相似于1443702394<br><br>1443702394<br><br>i44nunao0g3o7vf2su0hnc5440
• 命令行链接redis,也能够查看到该key以及对应的值
• 若是想用php链接redis cluster,须要使用predis扩展
• 安装方法相似phpredis,predis扩展地址https://github.com/nrk/predis
实例:
[root@localhost 01]# vim /usr/local/php-fpm/etc/php.ini [aming.com] listen = /tmpaming.sock lsiten.mode = 666 user = php-fpm grou = php-fpm pm = dynamic pm.max_children = 50 pm.start_servers = 20 pm.min_spare_servers = 5 pm.maxpare_servers = 35 pm.max_requests = 500 rlimit_files =1024 session.save_handler = "redis" //更改或增长 session.save_path = "tcp://127.0.0.1:6379" [root@localhost phpredis-develop]# /etc/init.d/php-fpm restart #重启服务 Gracefully shutting down php-fpm . done Starting php-fpm done [root@localhost phpredis-develop]# vim /etc/redis.conf requirepass #搜索的内容 requirepass aming>com 前面添加# 重启服务 [root@localhost phpredis-develop]# killall redis-server [root@localhost phpredis-develop]# redis-server /etc/redis.conf 测试 [root@localhost phpredis-develop]# cd /data/wwwroot/default/ [root@localhost default]# ls #下面 有m.php 文件 index.html vhost m.php info.php [root@localhost phpredis-develop# cat m.php [root@localhost phpredis-develop]# cat 1.php #1.php是关于session [root@localhost default]# curl localhost/1.php #多执行几回 [root@localhost 01]# redis cli #查看执行的记录 [root@localhost 01]# [root@localhost 01]#
• 为了节省资源,咱们能够在一台机器上启动两个redis服务
• cp /etc/redis.conf /etc/redis2.conf
• vim /etc/redis2.conf //须要修改port,dir,pidfile,logfile
• 还要增长一行
• slaveof 127.0.0.1 6379
• 若是主上设置了密码,还须要增长
• masterauth aminglinux>com //设置主的密码
• 启动以前不要忘记建立新的dir目录
• redis-server /etc/redis2.conf
• 测试:在主上建立新的key,在从上查看
• 注意:redis主从和mysql主从不同,redis主从不用事先同步数据,它会自动同步过去
实例:
搭建主从
[root@localhost 01]# cp /etc/redis.conf /etc/redis2.conf [root@localhost 01]# vim /etc/redis2.conf //须要修改port,dir,pidfile,logfile port 6380 #端口修改为6380 pidfile /var/run/redis_6380.pid logfile '/var/log/redis.log' 修改为'/var/log/redis2.log' dir /data/redis 改为 dir /data/redis2 slaveof 127.0.0.1 6379 增长一行 启动 [root@localhost 01]# mkdir /data/redis2/ [root@localhost 01]# redis-server /etc/redis2.conf [root@localhost 01]# ps aux | grep redis #查看进程 [root@localhost 01]# netstat -lntp # 查看redis-server的端口 [root@localhost 01]# redis-cli -h 127.0.0.1 -p 6380 127.0.0.1:6379> keys * 1) "k2" 2) "zseta" 3) "list2" 4) "setb" 5) "k3" 6) "mykey" 7) "k1" 8) "seta" 9) "set3" 10) "list1\xc2\xa0" 11) "hash1" 12) "set1" 13) "user1" 127.0.0.1:6380 > aming get dir 127.0.0.1:6380 > aming get dbfilename 127.0.0.1:6380 > aming get * #查看全部的元素 [root@localhost 01]# vim /etc/redis.conf slave-read-only yes #设置只读模式 [root@localhost 01]#redis-cli -h 127.0.0.1 -p 6380 127.0.0.1:6379> keys * (error)READONLY You can't write against a read only slave.
常见问题:
一、为啥,启动的时候,只用redis-server /etc/redis.conf 命令就能启动,而不是src/redis-server /etc/redis.conf 呢
答:由于你的redis-server命令已经放到了PATH里面了。 你which redis-server能显示路径出来,说明已经放到PATH里了。
二、,Redis启动时提示 Redis配置文件194行always-show-logo yes
答:找到缘由了。。。由于以前安装过Redis,冲突了
三、配置了redis的RDB模式的持久化,也在redis 更新了数据 为何不会自动生成一个备份的文件呢?
答:要重启服务才生效。
四、127.0.0.1:6379> SET key "123 100"
OK
这样就能够啦。
答:这样写的话, value的值是123 100, 而不是设置过时时间为100了吧
五、每次重启redis,都会生成一个新的dump.rdb 文件,我备份的rdb文件是123.rdb,把备份的123.rdb 拷到dir目录下,同时重命名为dump.rdb, 查询k 依然为空,,怎么备份恢复
答:把123.rdb 更名为dump.rdb, 再重启。
恢复优先使用aof,因而关闭aof以后就能成功经过dump.rdb 恢复备份了
六、使用bgsave 把数据存储到rdb文件后,备份了rdb文件,使用flushall 清空全部数据库k,杀掉redis进程,把rdb备份文件从新拷回redis数据目录中后,重启redis,使用 keys * 查询k,显示为空,这是为何??
答:在清数据以前,就要将dump.rdb 文件备份好,查看使用的dbfile是否是这个rdb文件
七、