redis 简单使用

2020-04-21 15:13:15

redis简单的教程参考地址 redis 简单使用

redis介绍

Redis和Memcached类似,也属于k-v数据存储
Redis官网 https://redis.io支持更多value类型,除了和string外,还支持hash、lists(链表)、sets(集合)和sorted sets(有序集合)
Redis是可以把数据存储在磁盘上的并且使用了两种文件格式:全量数据(RDB)和增量请求(aof)。一般叫做redis持久化
全量数据格式是把内存中的数据写入磁盘,便于下次读取文件进行加载。
增量请求文件则是把内存中的数据序列化为操作请求,用于读取文件进行replay得到数据,这种类似于mysql binlog。随时间而越来越大,其中有些内容是没有用的。
Redis的存储分为内存存储、磁盘存储和log文件三部分。内存存储和memcached一样,磁盘存储指RDB,log文件指aof。

redis安装

下载安装

[root[@abc](https://my.oschina.net/aaaaaa) src]# wget http://download.redis.io/releases/redis-4.0.11.tar.gz

redis 不需要初始化,可直接编译安装

[root[@abc](https://my.oschina.net/aaaaaa) src]# tar zxvf redis-4.0.11.tar.gz 
[root[@abc](https://my.oschina.net/aaaaaa) src]# cd redis-4.0.11
[root[@abc](https://my.oschina.net/aaaaaa) redis-4.0.11]# make
[root[@abc](https://my.oschina.net/aaaaaa) redis-4.0.11]# make install

拷贝配置文件至/etc下

[root@abc redis-4.0.11]# cp redis.conf /etc/redis.conf

编辑配置文件

[root@abc redis-4.0.11]# vim /etc/redis.confdaemonize yeslogfile "/var/log/redis.log"dir /data/redisappendonly yesdaemonize yes 表示redis为后台启动,终端继续做其他事情logfile "/var/log/redis.log" 定义redis的日志路径dir /data/redis 定义redis的RDB,aof文件的存放路径appendonly yes 开启aof日志 在dir定义的目录下存aof文件

创建RDB的目录

[root@abc redis-4.0.11]# mkdir -p /data/redis

修改内核参数

[root@abc redis-4.0.11]# sysctl vm.overcommit_memory=1[root@abc redis-4.0.11]# echo never > /sys/kernel/mm/transparent_hugepage/enabled 上面两条命令是为了不让系统告警(原是在redis日志中提示),不输入也没关系。想让机器启动就加载两条命令可以放到/etc/rc.local中

启动redis

[root@abc redis-4.0.11]# redis-server /etc/redis.conf [root@abc redis-4.0.11]# ps aux | grep redisroot     42198  0.3  0.2 145308  2196 ?        Ssl  20:22   0:00 redis-server 127.0.0.1:6379root     42219  0.0  0.0 112720   980 pts/0    S+   20:22   0:00 grep --color=auto redis[root@abc redis-4.0.11]#

redis持久化

Redis持久化表示数据存入磁盘中。Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)

rdb

就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上redis.conf上有定义RDB的触发时间来持久化save 900 1 #表示每15分钟且至少有1个key改变,就触发一次持久化 save 300 10 #表示每5分钟且至少有10个key改变,就触发一次持久化save 60 10000 #表示每60秒至少有10000个key改变,就触发一次持久化

aof

是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。redis.conf定义的关于aof的参数appendonly yes  #如果是yes,则开启aof持久化appendfilename “appendonly.aof” # 指定aof文件名字appendfsync everysec #指定fsync()调用模式,有三种no 隔一段时间来记录磁盘中,最不安全,always 每写入指令就记录,耗费资源大,everysec 每秒记录,默认这种方式。

RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。

如果没有数据持久化的需求,也完全可以关闭RDB和AOF方式

save “”  #这样可以禁用rdb持久化,并把其他save注释掉

redis数据类型

string

string为最简单的类型,与Memcached一样的类型,一个key对应一个value,其支持的操作与Memcached的操作类似,它的功能更丰富。设置可以存二进制的对象。

string操作

[root@abc redis-4.0.11]# redis-cli 127.0.0.1:6379> set key 111OK127.0.0.1:6379> get key"111"
127.0.0.1:6379> 

[root@abc redis-4.0.11]# redis-cli 127.0.0.1:6379> set key 111OK127.0.0.1:6379> get key"111"
127.0.0.1:6379> mset k1 a k2 b k3 cOK127.0.0.1:6379> mget k1 k2 k31) "a"
2) "b"
3) "c"
127.0.0.1:6379>

list

list 链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
使用 list 结构,我们可以轻松地实现最新消息排行等功能(比如新浪微博的 TimeLine )。list 的另一个应用就是消息队列,可以利用 list 的 push操作,将任务存在 list 中,然后工作线程再用pop操作将任务取出进行执行。

list操作

链表中推进新数据127.0.0.1:6379> lpush list1 "lan"(integer) 1127.0.0.1:6379> lpush list1 "ran"(integer) 2127.0.0.1:6379> lpush list1 "nan"(integer) 3查看键值127.0.0.1:6379> lrange list1 0 -11) "nan"2) "ran"3) "lan"链表中拉出数据127.0.0.1:6379> lpop list1"nan"127.0.0.1:6379> lrange list1 0 11) "ran"2) "lan"127.0.0.1:6379>

set

set 集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。

set操作

新建集合及元素127.0.0.1:6379> sadd set1 a(integer) 1127.0.0.1:6379> sadd set1 b(integer) 1127.0.0.1:6379> sadd set1 c(integer) 1127.0.0.1:6379> sadd set6 a 1 c 2(integer) 4127.0.0.1:6379> 查看集合元素127.0.0.1:6379> smembers set11) "a"2) "c"3) "b"127.0.0.1:6379> smembers set61) "2"2) "1"3) "a"4) "c"127.0.0.1:6379> 并集127.0.0.1:6379> sunion set1 set61) "b"2) "1"3) "a"4) "2"5) "c"127.0.0.1:6379> 交集127.0.0.1:6379> sinter set1 set61) "a"2) "c"127.0.0.1:6379> 差集127.0.0.1:6379> sdiff set1 set61) "b"127.0.0.1:6379> 删除元素127.0.0.1:6379> srem set1 a b(integer) 2127.0.0.1:6379> smembers set11) "c"127.0.0.1:6379>

sorted set

sorted set 有序集合,它比set多了一个权重参数score,使得集合中的元素能够按 score 进行有序排列,比如一个存储全班同学成绩的集合,其集合 value 可以是同学的学号,而 score 就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。

sorted set操作

新建集合并添加带权重的元素127.0.0.1:6379> ZADD sset1 1 lan(integer) 1127.0.0.1:6379> ZADD sset1 2 lan2(integer) 1127.0.0.1:6379> ZADD sset1 3 lan3(integer) 1127.0.0.1:6379> 查看有序集合127.0.0.1:6379> zrange sset1 0 -11) "lan"2) "lan2"3) "lan3"127.0.0.1:6379> 倒序127.0.0.1:6379> zrevrange sset1 0 -11) "lan3"2) "lan2"3) "lan"127.0.0.1:6379>

hash

hash 哈希表,类似于多个k-v组成的表。在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。

hash操作

添加hash数据127.0.0.1:6379> hset hash1 name ln(integer) 1127.0.0.1:6379> hset hash1 age 18(integer) 1127.0.0.1:6379> hset hash1 hobby music(integer) 1127.0.0.1:6379> 查看hash表中数据127.0.0.1:6379> hget hash1 age"18"127.0.0.1:6379> hget hash1 hobby"music"127.0.0.1:6379> 查看整个hash表127.0.0.1:6379> hgetall hash11) "name"2) "ln"3) "age"4) "18"5) "hobby"6) "music"127.0.0.1:6379>

redis常用操作

string

创建一个新的 k-v   格式: set 键名 值

获取 k-v     格式: get  键名

检测k-v是否存在,没有即创建k-v     格式:setnx 键名 值

127.0.0.1:6379> setnx key1 c(integer) 1       返回值为1 代表没有这个k-v,即创建这个 k-v127.0.0.1:6379> get key1"c"
127.0.0.1:6379> setnx key1 c(integer) 0    返回值为0  表示已有此 k-v127.0.0.1:6379> 

给k-v设置过期时间
格式1:set 键名 值 ex 时间(单位:秒)
格式2:setex 键名 时间(单位:秒) 值

127.0.0.1:6379> set key1 rn ex 3 
OK127.0.0.1:6379> get key1"rn"
127.0.0.1:6379> get key1(nil)
127.0.0.1:6379> 

连续创建多个k-v      格式:mset 键名1 值1 键名2 值2 ...

连续获取多个k-v      格式:mget 键名1 键名2 ...

list

从上往下插入值       格式: lpush  链名 值查看链值            格式: lrange 链名 初始下标  最后下标从上到下取值         格式: lpop 链名从下到上插入值       格式: rpush 链名 值从下到上取值         格式: rpop 链名在某个值上 插入值    格式: linsert  键名 before 某值 插入的值127.0.0.1:6379> lrange list1 0 -11) "ran"2) "lan"127.0.0.1:6379> linsert list1 before lan jkl(integer) 3127.0.0.1:6379> lrange list1 0 -11) "ran"2) "jkl"3) "lan"127.0.0.1:6379> 在某个值下 插入值     格式: linsert  键名 after 某值 插入的值127.0.0.1:6379> linsert list1 after lan abc(integer) 4127.0.0.1:6379> lrange list1 0 -11) "ran"2) "jkl"3) "lan"4) "abc"127.0.0.1:6379> 修改某个指定值        格式: lset 键名 下标 修改的值查看链中某值          格式: lindex 键名 下标 查看链中值数          格式: llen 键名

set

新建集合添加元素       格式: sadd 集合名 元素值

查看集合中所有元素     格式: smembers 集合名

删除元素              格式: srem 集合名 删除的元素值

随机取元素 并删除      格式: spop 集合名 取出的个数

随机取元素 不删除      格式: srandmember 集合名 取出的个数

求差集                 格式: sdiff 集合1 集合2 (以集合1为标准)

求差集 并存储到新集合    格式: sdiffstore 新集合 集合1 集合2 (以集合1为标准)

求交集                 格式:  sinter 集合1 集合2

求交集 并存储到新集合    格式: sinterstore 新集合 集合1 集合2 

求并集                 格式: sunion 集合1 集合2

求并集 并存储到新集合    格式: sunionstore 新集合 集合1 集合2

判断元素是否属于某个集合  格式: sismember 集合名 元素

sorted set

添加带权重的元素给集合    格式:zadd 集合名 权重1 元素1 ...

查看有序集合            格式:zrange 集合名 初始下标 最后下标

删除元素               格式:zrem 集合名 删除的元素值 ...

查看元素的索引值        格式:zrank 集合名 查看的元素值

反序查看元素的索引值    格式:zrevrank 集合名 查看的元素值

反序显示所有元素,可带分值  格式:zrevrange 集合名 初始下标 最后下标 [withscores]查看有序集合中共有多少个元素  格式:zcard 集合名

查看某个权重范围有多个元素  格式:zcount 集合名 初始权重 结束权重

查看某个权重范围的元素值,可带分值  格式:zrangebyscore 集合名 初始权重 结束权重 [withscores]删除某个权重范围的元素值   格式:zremrangebyscore 集合名 初始权重 结束权重

删除某个索引范围的元素值    格式:zremrangebyrank 集合名 初始下标 最后下标

hash

添加hash数据        格式:hset hash表名 键名 值

查看整个hash表      格式:hgetall hash表名

查看hash表中的某个数据  格式:hget hash表名 键名

添加多个hash数据     格式:hmset hash表名 键名1 值1 ...

查看hash表中的多个数据  格式:hmget hash表名 键名1 ...

删除指定的键值       格式:hdel hash表名 键名1 ...

查看表中所有的键名    格式:hkeys hash表名

查看表中所有的值      格式:hvals hash表名

查看表中总的k-v个数    格式:hlen hash表名

redis 操作键值

查看所有键 格式:keys *

127.0.0.1:6379> keys *
 1) "key"
 2) "list1"
 3) "hash1"
 4) "set1"
 5) "sset2"
 6) "set3"
 7) "k3"
 8) "k1"
 9) "set6"10) "sset3"11) "set2"12) "sset1"13) "k2"127.0.0.1:6379> 支持模糊匹配127.0.0.1:6379> keys set*1) "set1"2) "set3"3) "set6"4) "set2"127.0.0.1:6379>

判断某个键是否存在

格式:exists 键名127.0.0.1:6379> exists set5(integer) 0127.0.0.1:6379> exists set6(integer) 1127.0.0.1:6379> 0 表示不存在,  1表示存在

删除指定键

格式:del 键名
127.0.0.1:6379> del set6(integer) 1
127.0.0.1:6379> get set6(nil)
127.0.0.1:6379>

给某个键设置过期时间

格式:expire 键名 过期时间
127.0.0.1:6379> expire set1 10
(integer) 1
127.0.0.1:6379>

查看键的过期时间

格式:ttl 键名127.0.0.1:6379> expire set1 10(integer) 1127.0.0.1:6379> ttl set1(integer) 8127.0.0.1:6379> ttl set1(integer) -2127.0.0.1:6379> ttl set3(integer) -1127.0.0.1:6379> 8 代表 还有多久过期   -2 该键值不存在   -1代表没有设置过 过期时间

取消过期时间

格式:persist 键名
127.0.0.1:6379> expire list1 100
(integer) 1
127.0.0.1:6379> ttl list1(integer) 95
127.0.0.1:6379> persist list1(integer) 1
127.0.0.1:6379> ttl list1(integer) -1127.0.0.1:6379>

随机返回一个键

格式:randomkey127.0.0.1:6379> randomkey"k3"
127.0.0.1:6379> randomkey"k1"
127.0.0.1:6379>

重命名键名称

格式:rename 旧键名 新键名
127.0.0.1:6379> rename list1 list_newOK127.0.0.1:6379> keys list_*
1) "list_new"
127.0.0.1:6379>

返回键类型

格式:type 键名
127.0.0.1:6379> type keystring127.0.0.1:6379> type list_newlist127.0.0.1:6379>

选择进入库

Redis自带有16个库,从0-15格式:select 库下标
127.0.0.1:6379> select 1OK127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]>

移动键到其他库里

格式:move 键名 库下标
127.0.0.1:6379> move key 1
(integer) 1
127.0.0.1:6379> select 1OK127.0.0.1:6379[1]> keys *
1) "key"
127.0.0.1:6379[1]>

返回当前数据库中键的个数

格式:dbsize127.0.0.1:6379[1]> dbsize(integer) 1
127.0.0.1:6379[1]>

清空当前库中的键

格式:flushdb127.0.0.1:6379[1]> flushdbOK127.0.0.1:6379[1]> dbsize(integer) 0
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]>

清空所有库中键

格式:flushall127.0.0.1:6379[1]> FLUSHALLOK

保存数据到rdb文件中

格式:save127.0.0.1:6379> SAVEOK

后台保存数据

格式:bgsave127.0.0.1:6379[1]> bgsaveBackground saving started127.0.0.1:6379[1]>

返回数据库状态信息

格式:info127.0.0.1:6379[1]> info# Serverredis_version:4.0.11redis_git_sha1:00000000redis_git_dirty:0redis_build_id:be1c6682cec9ff0eredis_mode:standaloneos:Linux 3.10.0-693.el7.x86_64 x86_64arch_bits:64multiplexing_api:epoll

获取所有配置参数

格式:config get *127.0.0.1:6379[1]> config get *
  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) ""
  5) "masterauth"
  6) ""
  7) "cluster-announce-ip"
  8) ""
  支持模糊匹配127.0.0.1:6379[1]> config get log*1) "logfile"2) "/var/log/redis.log"3) "loglevel"4) "notice"127.0.0.1:6379[1]>

更改配置参数

格式:config set 参数名 值
127.0.0.1:6379[1]> config get timeout1) "timeout"
2) "0"
127.0.0.1:6379[1]> 
127.0.0.1:6379[1]> config set timeout 100OK127.0.0.1:6379[1]> config get timeout1) "timeout"
2) "100"
127.0.0.1:6379[1]>

数据恢复

先定义或者确定dir目录和dbfilename,然后把备份的rdb文件放到dir目录下面,重启redis服务即可恢复数据127.0.0.1:6379> config get dir1) "dir"2) "/data/redis"127.0.0.1:6379> config get dbfilename1) "dbfilename"2) "dump.rdb"127.0.0.1:6379>

redis 安全设置

由于redis是以root用户登录的 而且redis默认是监听全文IP的。黑客可以轻易登录redis服务器后可以把他的公钥通过dir/dump.rdb来存放到/ssh/.authorized_kyes下来ssh服务器

修改监听IP

[root@abc redis-4.0.11]# vim /etc/redis.conf bind 127.0.0.1如有多个IP,以空格分开

修改监听端口

port 6379       配置文件是  /etc/redis.conf

设置登录密码

requirepass lantern密码为 lantern

重启redis服务

[root@abc redis-4.0.11]# killall redis-server[root@abc redis-4.0.11]# redis-server /etc/redis.conf

使用密码登录

[root@abc redis-4.0.11]# redis-cli -a 'lantern'Warning: Using a password with '-a' option on the command line interface may not be safe.127.0.0.1:6379> 

报错:Warning: Using a password with '-a' option on the command line interface may not be safe.
Could not connect to Redis at 127.0.0.1:6379: Connection refused
Could not connect to Redis at 127.0.0.1:6379: Connection refusednot connected>
如果出现如上情况,需再次执行配置文件后  
即此命令redis-server /etc/redis.conf   在连接 即可

别名config命令

rename-command CONFIG lan127.0.0.1:6379> config get *
(error) ERR unknown command `config`, with args beginning with: `get`, `*`, 
127.0.0.1:6379> lan get *  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) "lantern"
  5) "masterauth"

禁止config命令

rename-command CONFIG ""127.0.0.1:6379> CONFIG GET *
(error) ERR unknown command `CONFIG`, with args beginning with: `GET`, `*`,

redis慢查询日志

reids和MySQL一样也有慢查询日志,并在配置文件下定义。

slowlog-log-slower-than 10000slowlog-max-len 128单位ms,表示慢于10000ms则记录日志,10000ms等于0.01定义日志长度,表示最多存128条日志

列出所有的慢查询日志

格式:slowlog get127.0.0.1:6379> SLOWLOG get1) 1) (integer) 2
   2) (integer) 1535036368
   3) (integer) 48
   4) 1) "keys"
      2) "*"
   5) "127.0.0.1:50734"
   6) ""2) 1) (integer) 1
   2) (integer) 1535036329
   3) (integer) 13
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:50734"
   6) ""3) 1) (integer) 0
   2) (integer) 1535036293
   3) (integer) 914
   4) 1) "COMMAND"
   5) "127.0.0.1:50734"
   6) ""127.0.0.1:6379> 显示最新的一条慢查询日志127.0.0.1:6379> SLOWLOG get 11) 1) (integer) 3
   2) (integer) 1535036370
   3) (integer) 24
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:50734"
   6) ""127.0.0.1:6379>

列出当前慢日志的条数

格式:slowlog len127.0.0.1:6379> SLOWLOG len(integer) 5
127.0.0.1:6379>

php安装redis模块

下载安装


  • 2020-01-30 11:19:58

    Android中添加两个(多个)FileProvider节点问题

    我们知道在android7.0,修改了对私有存储的限制,导致在获取资源的时候,不能通过Uri.fromFile(..)来获取uri了,但是在写入数据的时候是可以通过Uri.fromFile(..)来获取uri的,android 官网给出的解决办法是通过FileProvider来解决这一问题,我们需要在AndroidManifest.xml 配制provider节点。

  • 2020-02-02 15:40:36

    Apache Commons IO之IOUtils优雅操作流

    在开发过程中,你肯定遇到过从流中解析数据,或者把数据写入流中,或者输入流转换为输出流,而且最后还要进行流的关闭,原始jdk自带的方法写起来太复杂,还要注意各种异常,如果你为此感到烦恼,那IOUtils可以让我们优雅的操作流。

  • 2020-02-02 19:24:38

    百度视频SDK,突然不能播放

    开发过程中,不知道什么时候开始视频不能播发了,怎么办都不行,其他项目没问题,线上都也没有问题,这可急躁完蛋我了,整了仨小时,还是那熊样。 哎。

  • 2020-02-04 18:43:10

    AssetManager.finalize() Timed Out 解决办法以及分析

    在我们的项目崩溃中,有一个比较常见的bug,就是 java.util.concurrent.TimeoutException android.content.res.AssetManager.finalize() timed out after 10 seconds 意思简单明了,就是说在AssetManager析构的时候发生了超时异常。

  • 2020-02-06 13:32:10

    android.os.NetworkOnMainThreadException

    在Android 4.0以上,网络连接不能放在主线程上,不然就会报错android.os.NetworkOnMainThreadException。但是4.0下版本可以不会报错。