Redis

 

本文使用linux安装Redis

Redis是单线程,所以少用时间长的命令

Redis的下载

进入官网下载即可。https://redis.io/download

然后进行一个编译:  make -j 4

然后执行:make install

可以看到redis下面的可执行文件:

然后执行redis-server,启动出现如下窗口证明启动成功。

然后新建一个窗口进行连接:

如果出现跟我一样的错误的话,redis也给出了四种解决方案

1.修改redis.conf配置文件,将绑定的ip地址端口号给注释见下图 

2.由于Linux上的redis处于安全保护模式,这就让你无法从虚拟机外部去轻松建立连接,这里就有两种解决方法,一种是在redis.conf中设置保护模式为no,见下图 

3.另外一种方式是加上安全认证,即redis默认是没有密码的可以直接登录,这里加上密码,配置见下图 

 

 4.好吧,此时你以为轻松解决问题了,于是再次在Linux启动redis服务器后,在外部连接还是报错,真是too young too native,起初我以为是配置没有生效,因为明明配置都写好了,于是杀掉redis的相关进程重启服务,结果发现还是没卵用。最后研究发现问题所在:之前启动redis-server并没有指定配置文件,而Linux上的redis比较操蛋的一点就是如果你不指定配置文件去启动,那么你做的修改就没有用,会读取默认配置(PS:至于这个默认配置在哪我也不清楚),于是用下面这种方式启动就可以使修改的配置文件生效,至于config rewrite命令我测试了并没有什么卵用。 

# 修改no 为yes,允许redis后台运行
daemonize yes 

然后重新启动,就可以set,get的玩耍了

 RedisAPI的使用

遍历所有key与key总数

keys *
dbsize

判断key是否存在,存在就返回1,不存在就返回0

exists key

删除命令,1和0

del key

设置key时间/ -1代表key存在,永不过期,-2代表key已经过期

expire key seconds
# key在seconds秒后过期
ttl key
# 查询key剩余时间
persist key
# 取消key过期时间

查询key的类型

type key

以上命令的时间复杂度:

keys o(n) 其它o(1)

  Redis的基本数据类型—— String

结构是: key:value 的形式

储存: set key value
key不存在,设置 setnx key value 0/1
key存在,设置   set key value xx

获取:
get key 批量获取: mget key key key 一次网络加N次命令
批量set: mset key value key value
删除:del key 自增1:incr key 自减1: decr key 自增k: incrby key k 自减k: incrby key k

set新的值,返回旧值 getset key newvalue
将value追加到旧value append key value
返回字符串长度     strlen key  注意中文

incrbyfloat key value 增加key对应值value
getrange key start end    截取字符串指定下标所有值
setrange  key index value 设置指定下标所有对应值

  Redis的基本数据类型—— Hash

储存格式:key  field value

获取:hget key field

存储:hset key field value

删除:hdel key field

是否存在:hexists key field

获取数量: hlen key 

hmget

hmset
返回所有hash key对应所有field和value     hgetall key
返回hash key对应所有field的value       hvals key
返回hash key对应所有field           hkeys key
hsetnx key field value 如果存在,则失败
hincrby key field int 自增int
hincrbyfloat key field float 自增float

   Redis的基本数据类型—— list

格式:key  elements
  有序,可重复,左右都可以存储弹出

左边添加,左边删除,  lpush  key value value value    lpop
右边添加,右边删除,  rpush  key value value value    rpop
插入,之前/之后:  linsert  key  before|after  value  newValue
lrem  key   count value  根据count的值,从列表中删除所有value相等的值,
  1,count>0,从左忘右删除count个value相等的值

  2, count<0,从右往左删除count个value相等的值

  3, count=0,删除所有value相等的值

ltrim  key  start  end     按照索引范围剪列表
lrange  key  start  end  获取列表知道索引范围所有item,包含end
lindex  key  index    获取下标元素
llen  key  获取列表长度
lset  key  index  newValue  更改index的值
blpop  key timeout  lpop阻塞版本,timeout是阻塞超时,0为永不阻塞

lrpop

LPUSH + LPOP=Stack

LPUSH + RPOP = Queue

LPUSH + LTRIM = Capped Collection

LPUSH + BRPOP = Message Queue

   Redis的基本数据类型—— set

结构:key  elements(不可重复)

  无序,不可重复,可以集合间操作

sadd key element  添加,如果element存在,则添加失败
srem key element  移除
scard  key  计算集合大小
sismember  key  判断key是否存在,存在返回1
srandmember  key  count    从集合随机挑count个元素
spop key  从集合随机弹出一个元素
smembers key 获取集合所有元素

sdiff key1 key2   key1和key2的差集
sinter  key1  key2  交集
sunion          并集
sdiff|sinter|sunion  + store    destkey  将差集交集并集结果保存到key中

   Redis的基本数据类型—— Zset

结构:key  score  value
根据score排序

zadd  key  score  element     score可重复
zrem  key  element  删除,可以删除多个
zscore  key  element  返回score
zincrby  key increScore  element  增加或减少increScore点分数
zcard  key  返回元素的总个数
Zrange key start end [WITHSCORES]   返回知道索引范围内的升序元素[分值]
Zrangebyscore key start end [WITHSCORES]   返回知道分数范围内的升序元素[分值]

 zcount  key minScore  maxScore  返回有序集合内在指定分数范围内的个数
zremrangebyrank key start end   删除指定排名内的升序元素
zremrangebyscore key minScore maxScore   删除指定分数内的升序元素

瑞士军刀——redis 

慢查询

发送命令——排队——执行命令——返回结果

slowlog-max-len=128         慢查询长度

slowlog-log-slower-than=10000    慢查询阈值  单位:微妙  1毫秒=1000微妙  ==0,记录所有,<0,不记录任何命令

可动态修改    config set slowlog-max-len 1000      config  set slowlog-log-slower-than   1000

slowlog get[n]  获取慢查询队列,

slowlog len    获取慢查询队列长度

slowlog reset    清空慢查询

pipeline流水线 

Pipeline pipline = jedis.pipline();

for (i=1;i<1000;i++){
    pipeline.hset()
}
pipeline.syncAndReturnAll();

发布订阅

角色:发布者(publisher),订阅者(subscriber),频道(channel)

 

publish  channel message   发送消息到channel频道

subscribe [channel]  订阅一个或多个

unsubscribe    取消频道

psubscribe [pattern]  订阅正则

消息队列,抢的功能

Bitmap,位图

HypertLogLog

基于HypertyLogLog算法,极小空间完成独立数量统计,本质还是字符串

pfadd key element [element......]    添加元素
pfcount key [key......]  计算hyperloglogs的独立总数

pfmerge destkey sourcekey [sourcekey.....] 合并多个hyperloglog

GEO

 geo key longitude latitude member [longitude latitude member]      增加地理位置信息
geopos  key member [member]  获取地理位置信息
geodist  key  member1 member2 [unit]    获取两个地址位置的距离,m km mi(英里) ft(尺)

Redis持久化

ROB 与MySQL Dump(快照,某时间点的完整备份),AOF与MySQL的BinLog(写日志)

RDB

redis,内存中的数据,保存为RDB文件(二进制)

redis,启动后自动加载ROB文件

触发机制


 

save(同步),bgsave(异步),自动

对redis发送save命令,redis会自动创建一个当前存储内容的RDB文件,返回ok,,,,阻塞

  如存在老的RDB文件,新替换老的,阻塞时间久


 

发送bgsave,响应Background  saving started,会使用fork(),创建一个子进程去执行,创建RDB,成功后响应

  fork()的时候会阻塞。但是创建后就不阻塞


 

自动生成RDB,使用的是bgsave

配置一个即可

配置  seconds  changes

save  900    1

save  300    10

save  60    10000

dbfilename  dump-${port}.rdb  生成rdb文件的名字

dir ./        生成文件所在的目录

stop-writes-on-bgsave-error  yes  生成rdb文件错误是否停止写入

rdbcompression  yes    对rdb文件是否采用压缩模式

rdbchecksum  yes  是否对rdb文件做检验

其它触发方式:

全量复制,debug reload  ,shutdown

总结:

RDB是Redis内存到硬盘的快照,用于持久化

save通常会阻塞

bgsave,不会阻塞,但是fork新进程的时候会阻塞

有些触发机制不容忽视

AOF

客户没写一条命令都记录到AOF文件中,redis重启后,将AOF加载过来

把命令记录到缓存区,缓存区写入AOF根据策略

三种策略,

always:每条命令都写入,不会丢失数据,硬盘开销大

everysec:每秒把缓存区,fsync到硬盘中,丢失1秒,默认值

no:操作系统决定,不可控,不用管

AOF重写,重复过期没有用的,优化命令,减少硬盘占用,加快恢复

bgrewriteaof。子进程重写,重写

auto-aof-rewrite-min-size  AOF重写需要的尺寸

auto-aof-rewrite-percentage   AOF文件增长率

appendonly   yes  开启AOF

appendfilename  "appendonle-${port}.aof"  文件名称

appendfsync  everysec  策略

dir  /

on-appendfsync-on-rewrite  yes  选择性能,允许丢失

 

Redis主从复制

主从复制

1,一个master可以有多个slave

2,一个slave只能有一个master

3,数据流是单向的,master到slave

全量复制两种实现方式:

偏移量允许为buffer缓存区大小,未验证

命令方式(异步):

1,slaveof  ip 端口,子节点指向父节点

2,master ip  端口,父节点指向子节点

取消复制,slaveof  no  one,子指向父

配置文件方式:

slaveof  ip  port

slave-read-only  yes  只读

部分复制:没懂

下面演示一下一主一从:

主不需要配置什么,在从Redis的配置文件上面加条命令指向主地址即可。如下图:

然后两个Redis启动后查看6380的信息如下:

然后查看从服务器的信息

然后进行操作如下:

 

 

Redis sentine_哨兵

 

 

Redis sentine可以监控多套Master与slave

 安装与配置

1,配置开启主从节点

2,配置开启sentinel监控主节点,(sentinel是特殊的redis)

3,实际应该很多台机器,我测试都在一台机器上测试

4,详细的配置节点

下面进行演示:

配置如下

master-7000

port 7000
daemonize yes
pidfile /var/run/redis-7000.pid
logfile "redis-7000.log"
dir 

slave-7001

port 7001
daemonize yes
pidfile /var/run/redis-7001.pid
logfile "redis-7001.log"
dir 

salveof  127.0.0.1 7000

slave-7002

port 7002
daemonize yes
pidfile /var/run/redis-7002.pid
logfile "redis-7002.log"
dir 

salveof  127.0.0.1 7000

sentinel-26379、sentinel-26380、sentinel-26381

port 26379
dir /root/logs/redis-log
logfile "26379.log"
sentinel monitor mymaster {ip} 7000 2 
sentinel down
-after-milliseconds mymaster 30000
sentinel parallel
-syncs mymaster 1
sentinel failover
-timeout mymaster 180000
daemonize yes

 

如下图,新建了三个配置Redis配置文件

然后,分别启动他们:可以看到下面的进程全部启动了。

可以看到master有两个子节点

然后拷贝Redis下的sentinel.conf,然后执行命令去掉空格和注释

 cat sentinel.conf |grep -v "#" |grep -v "^$"  > sentinel-26379.conf

可以选择添加守护进程配置:

daemonize yes

sentinel的启动命令是

redis-sentinel sentinel-26379.conf

启动后,查看配置文件,可以发现多了几行,这就是sentinel监听master与slave

 进入sentinel查看info,可以看到监听信息

 

可以看到,三个redis与三个哨兵都启动成功。

可以看到哨兵是三个,说明哨兵之间可以互相感知的

然后我杀死了master进程,然后哨兵进行选举把7001设置为master

我们可以去看一下7001的info,可以看到7001为主了,而且子节点只剩下一个

然后我们把7000重启,看看会发生什么呢。

自动变成了7001的slave,这就是哨兵帮我们操作了。

 Java客户端连接哨兵

package com.mmall.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

/**
 * @Class RedisUtils
 * @Description Redis工具类
 * @Author wanghao
 * @createTime 9:31 2018/8/5
 **/
public class RedisUtils{


    private static JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

    private static Jedis jedis;

    private static JedisSentinelPool jedisSentinelPool;

    private static JedisPool jedisPool;
//    static {
//        jedisPoolConfig.setMaxIdle(100);
//        jedisPoolConfig.setMaxTotal(1000);
//        jedisPoolConfig.setMaxWaitMillis(10000);
//        jedisPoolConfig.setTestOnBorrow(true);
//        jedisPool = new JedisPool(jedisPoolConfig,"ip",7000);
//        jedis = jedisPool.getResource();
//    }
    static {
        Set<String> redisList = new HashSet<>();
        redisList.add("ip:26379");
        redisList.add("ip:26380");
        redisList.add("ip:26381");
        jedisSentinelPool=new JedisSentinelPool("mymaster",redisList);
    }

    public static void main(String[] args) {

//        jedis.set("zhangsan","张三");
//        System.out.println(jedis.get("zhangsan"));
    }
}
Sentinel

 

如图所示,上面已经正常连接了。然后进行无限循环操作。

如果遇到连接不上,可以查看是否redis开启保护模式:此设置为yes的时候就是保护模式,要么设置为no或者添加密码

protected-mode no

 然后模拟setget操作。

 Redis Cluster

 

 

 

安装Redis报错及解决

1、make -j  4 的时候报如下错误:

  

1、先查看是否安装c++的编译器; 执行 yum -y install gcc-c++

安装完c++编译器后 再次 make 若报此错

2、执行 make clean 后再次 执行 make ,再检查redis-x.x.x/src 目录下有没有 redis-server、redis-cli 和 /usr/local/bin下有没有
若无,则把redis-x.x.x 文件夹删掉,再解压一次redis的压缩包,cd进入 redis-x.x.x 中, make 一下 即可

原文:https://blog.csdn.net/weixin_40493969/article/details/81150469 

 

posted @ 2019-08-12 15:04  苦心明  阅读(218)  评论(0)    收藏  举报