• Redis详解


    一、Redis安装

    二、Redis命令

    三、StackExchange.Redis

    四、四大结构体

    五、Redis数据结构之String

    六、Redis数据结构之List

    七、Redis数据结构之Hash表

    八、Redis数据结构之Set

    九、Redis数据结构之sorted_set

    十、Redis数据结构之hyperloglog

    十一、Transactions

    十二、发布/订阅

    十三、redis驱动批量执行命令

    十四、Redis使用Lua

    十五、Redis两种持久化方式

    十六、搭建Redis主-备(mster-slave)

    十七、搭建Redis主-备(mster-slave)+哨兵(sentinel)

    十八、 web监控【redislive】

    十九、 搭建cluster(集群) 

    redis中文文档:http://www.redis.cn/

    redis可视化工具:https://raw.githubusercontent.com/caoxinyu/RedisClient/windows/release/redisclient-win32.x86.2.0.exe

    一、Redis安装

    1,Windows安装

    ①下载redis并安装msi文件

    https://github.com/MicrosoftArchive/redis

    ②设置环境变量

     

    ③运行server

    redis-server D:Redis edis.windows-service.conf

    ④运行client

    redis-cli

    2,Linux安装

    ①进入usr-》local目录下

    ②$ wget http://download.redis.io/releases/redis-4.0.6.tar.gz   下载redis

    ③$ tar xzf redis-4.0.6.tar.gz  解压

    ④$ cd redis-4.0.6  进入目录

    ⑤$ make  编译

    ⑥编译好之后进入src文件下,发现编译好了几个可执行文件。将这几个文件考到sbin下面

    ⑦配置环境变量

    /etc/profile 打开文件,设置

    export PATH=$PATH:/usr/local/redis-4.0.6/sbin

    ⑧重启centOS 

    二、Redis命令

    set username jack 设置缓存

    get username 读取缓存

    keys * 查看所有的key

    flushall 清空所有数据(没有一点安全保证)

    bgsave 立马持久化缓存信息

    bind 127.0.0.1  如果没有注销掉bind,则Redis监听所有链接

    protected-mode yes【yes只能回路地址127.0.0.1 本地访问】

    生产环境一般配置
    #bind
    protected-mode no

    port 6379 配置redis端口

    dir ./ 配置rdb和logfile的存放位置(例如:dir /usr/redis/sbin/db)

    databases 16设置数据库的数量

    logfile "server_log.txt" 指定日志文件名称

    loglevel notice 日志记录级别

    rename-command 改变命令的名称

    redis-cli -h 192.168.1.102 -p 6379 远程链接redis

    redis-cli -h 192.168.1.102 -p 6379 -a 123456 --stat 监控redis状态

    设置密码:
    
    在配置文件中设置requirepass(例如 requirepass 123456)
    连接redis服务器时需要带上密码(例如:redis-cli -h 192.168.1.102 -p 6379 -a 123456
    redis远程链接失败总结
    ①看看redis-server指向的配置文件是否指定对了
    ②conf配置
    #bind
    protected-mode no
    ③关闭centOS的防火墙
    systemctl stop firewalld.service #停止firewall
    systemctl disable firewalld.service #禁止firewall开机启动

    1,设置key的过期时间
    persist【O(1)】:PERSIST key【移除给定key的生存时间】
    expire【O(1)】:EXPIRE key seconds【设置key的过期时间,单位秒】
    pexpire【O(1)】:PEXPIRE key milliseconds【设置key的过期时间,单位毫秒】
    expireat【O(1)】:EXPIREAT key timestamp【设置key的过期时间,单位时间戳】

    2,Redis配置

    ①maxmemory设置最大内存空间(默认注释)

    ②maxmemory-policy最大内存空间策略(默认注释)

    策略:

    # volatile-lru -> 删除使用LRU算法设置过期的key
    # allkeys-lru ->根据LRU算法删除任何key
    # volatile-random -> 删除过期集合的key
    # allkeys-random ->删除一个随机key,任何key
    # volatile-ttl ->删除最接近过期时间的key
    # noeviction -> 如果内存写满,则抛异常

    lru :最久未使用的 

    三、StackExchange.Redis

    wireshark 网络封包分析软件

    nuget StackExchange.Redis

    public static class RedisCache
        {
            private static ConnectionMultiplexer connection;
            private static IDatabase database;
    
            static RedisCache()
            {
                var options=new ConfigurationOptions()
                {
                    Password = "123456",
                    EndPoints = { { "192.168.1.101", 6379 } }
                };
                connection = ConnectionMultiplexer.Connect(options);
                database = connection.GetDatabase();
            }
            public static void Set(string key,string str)
            {
                database.StringSet(key, str);
            }
            public static string Get(string key)
            {
               return database.StringGet(key);
            }
        }
    RedisCache

    https://stackexchange.github.io/StackExchange.Redis/Configuration

    四、四大结构体

    1,RedisServer struct

    2,RedisDb struct 标识一个db,config配置默认为16个RedisDb 

    3,RedisObject struct 也就是对象化的数据结构表示

    4,SDS struct char[] 一个包装类(存放字符串)

     

    五、Redis数据结构之String

    1,get/set 命令(时间复杂度O(1))

    SET key value [EX seconds] [PX milliseconds] [NX|XX]

    • EX seconds – 设置键key的过期时间,单位时秒
    • PX milliseconds – 设置键key的过期时间,单位时毫秒
    • NX – 只有键key不存在的时候才会设置key的值
    • XX – 只有键key存在的时候才会设置key的值
    案例:使用分布式锁
    set a a NX
    业务操作
    del a

    2,incr/decr/incrby/decrby

    incr 自增加1(i++)

    decr自增减1(i--)

    incrby自增加n(i=i+n)

    decrby自增减n(i=i-n)

    如果存放string中的value是int,则内存使用int存储值

    3,ttl key 查询key还有多长时间过期(-2 表示过期)

    4,PSETEX/SETEX 

    PSETEX key milliseconds value
    SETEX key seconds value
    PSETEX和SETEX一样,唯一的区别是到期时间以毫秒为单位,而不是秒。

    六、Redis数据结构之List

    双向链表

    可以用作队列(lpush/rpop、rpush/lpop)或者栈(lpush/lpop、rpush/rpop)

    一般用作队列

    lpush:LPUSH key value [value ...]【将所有指定的值插入到存于 key 的列表的头部。如果 key 不存在,那么在进行 push 操作前会创建一个空列表】

    lpop:LPOP key【移除并且返回 key 对应的 list 的第一个元素】

    rpush:RPUSH key value [value ...]【向存于 key 的列表的尾部插入所有指定的值。如果 key 不存在,那么会创建一个空的列表然后再进行 push 操作】

    rpop:RPOP key【移除并返回存于 key 的 list 的最后一个元素】

    llen:LLEN key【返回存储在 key 里的list的长度。 如果 key 不存在,那么就被看作是空list,并且返回长度为 0】

    blpop:BLPOP key [key ...] timeout【弹出最前面的值,如果列表中没有值,会阻塞】
    brpop:BRPOP key [key ...] timeout【弹出最后面的值,如果列表中没有值,会阻塞】
    注:timeout:等待时间,单位秒。0:标识永久等待
    lrange:LRANGE key start stop【返回存储在 key 的列表里指定范围内的元素】
    注:start stop位数组的下标

    linsert:LINSERT key BEFORE|AFTER pivot value【把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面】
    注:BEFORE为之前/AFTER为之后
    pivot:list中的值

    七、Redis数据结构之Hash表

    hget:HGET key field【返回 key 指定的哈希集中该字段所关联的值】
    hset:HSET key field value
    设置 key 指定的哈希集中指定字段的值。
    如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。
    如果字段在哈希集中存在,它将被重写。
    field:字典中的key
    value:字典中的value

    hdel:HDEL key field [field ...]【从 key 指定的哈希集中移除指定的域】
    hexists:HEXISTS key field【返回hash里面field是否存在】
    hgetall:HGETALL key【返回 key 指定的哈希集中所有的字段和值】
    hkeys:HKEYS key【返回 key 指定的哈希集中所有字段的名字】
    hlen:HLEN key【返回 key 指定的哈希集包含的字段的数量】
    hmget:HMGET key field [field ...]【返回 key 指定的哈希集中指定字段的值】
    hmset:HMSET key field value [field value ...]【设置 key 指定的哈希集中指定字段的值】
    hvals:HVALS key【返回 key 指定的哈希集中所有字段的值】

    八、Redis数据结构之Set

    无value的字典

    sadd【O(N)】:SADD key member [member ...]【添加一个或多个指定的member元素到集合的 key中】
    scard【O(1)】:SCARD key【返回集合存储的key的基数 (集合元素的数量)】
    sismember【O(1)】:SISMEMBER key member【检查成员member是否存在集合中】
    smembers【O(N)】:SMEMBERS key【返回key集合所有的元素】
    spop【O(1)】:SPOP key [count]【随机从集合弹出count(默认1)个值】
    srem【O(N)】:SREM key member [member ...]【在key集合中移除指定的元素】

    差集、交集、并集
    sdiff【O(N)】:SDIFF key [key ...]【差集】
    sdiffstore【O(N)】:SDIFFSTORE destination key [key ...]【将差集保存到destination中】
    sinter【O(N*M)】:SINTER key [key ...]【交集】
    sinterstore【O(N*M)】:SINTERSTORE destination key [key ...]【将交集保存到destination中】
    sunion【O(N)】:SUNION key [key ...]【并集】
    sunionstore【O(N)】:SUNIONSTORE destination key [key ...]【将并集保存到destination中】

    九、Redis数据结构之sorted_set

    一般用做优先级队列

    zadd【O(log(N))】:ZADD key [NX|XX] [CH] [INCR] score member [score member ...]【将所有指定成员添加到键为key有序集合(sorted set)里面】
    XX: 仅仅更新存在的成员,不添加新成员。
    NX: 不更新存在的成员。只添加新成员。
    CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。
    INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。
    zcard【O(1)】:ZCARD key【返回key的有序集元素个数】
    zrange【O(log(N)+M)】:ZRANGE key start stop [WITHSCORES]【从小到大排序。显示字典信息(WITHSCORES 显示出key)】【例如:zrange sdic 0 -1 withscores】
    zrevrange【O(log(N)+M)】:ZREVRANGE key start stop [WITHSCORES]【从大到小排序。显示字典信息(WITHSCORES 显示出key)】【例如:zrevrange sdic 0 -1 withscores】
    zremrangebyrank【O(log(N)+M)】:ZREMRANGEBYRANK key start stop【移除有序集key中】
    0:最小
    -1:最大
    -2:第二大。。以此类推

    十、Redis数据结构之hyperloglog

    等于distinct+count
    计算不是100%准确
    使用场景:计算某一天独立ip访问数量
    pfadd 20180125 192.168.1.1 192.168.1.1 192.168.1.2【O(1)】
    pfcount 20180125【O(1)】

    十一、Transactions

    multi:开启一个事务
    exec:提交事务
    discard:回滚事务

    watch【乐观锁】:WATCH key [key ...]

    例如客户端1watch username并开启了一个事务。当在另一个客户端2修改了username值的时候。客户端1事务exec会执行失败(回滚)

    十二、发布/订阅

    subscribe:SUBSCRIBE channel [channel ...]【订阅频道】
    publish:PUBLISH channel message【发布消息】

     psubscribe:PSUBSCRIBE pattern [pattern ...]【订阅给定的模式的频道】

    十三、redis驱动批量执行命令

            static void Main(string[] args)
            {
                var con= ConnectionMultiplexer.Connect("192.168.1.102:6379");
                var db = con.GetDatabase();
    
                var batch= db.CreateBatch();
    
                batch.SetAddAsync("username", "hunter");
                batch.ListInsertBeforeAsync("list", "1", "2");
                batch.HashSetAsync("dic", "username", "jack");
                batch.Execute();
                Console.ReadKey();
            }

    十四、Redis使用Lua

    Lua工具下载地址:LuaForWindows_v5.1.4-46.exe

    1,命令
    EVAL script numkeys key [key ...] arg [arg ...]
    script:指定lua脚本的路径。或者直接写lua脚本
    numkeys:制定参数的个数
    key:在脚本中使用到的key(KEYS 全局key集合。单项:KEYS[1])
    arg:在脚本中使用到的arg(ARGV 全局arg集合。单项:ARGV[1])
    注:KEYS[0]或者ARGV[0]是错误的写法

    2,Lua脚本调用Redis
    redis.call('set','foo','bar')
    redis.pcall('hset','dic','key','value')
    redis.call() 与 redis.pcall()很类似, 他们唯一的区别是当redis命令执行结果返回错误时,
    redis.call()将返回给调用者一个错误,而redis.pcall()会将捕获的错误以Lua表的形式返回

    3,案例
    ①直接嵌入lua脚本

    > eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
    1) "key1"
    2) "key2"
    3) "first"
    4) "second"

    ②调用独立的lua脚本

    return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}
    lua文件
    redis-cli --eval C:UsersHunter2DesktopLua	ext.lua a b , a b
    1) "key1"
    2) "key2"
    3) "first"
    4) "second"

    ③更高级的调用

    需求:输入的参数在集合中存在,则打印出来

    local key=KEYS[1]
    local args=ARGV
    
    local result={}
    local list=redis.call("smembers",key)
    for m,n in ipairs(args) do
        local exists= redis.call("sismember",key,n)
        if(exists==1)then
        table.insert(result,n)
        end
    end
    return result
    Lua文件
    C:WINDOWSsystem32>redis-cli --eval C:UsersHunter2DesktopLua	ext.lua list , 1 2 3 10
    1) "1"
    2) "2"
    3) "3"

    注:逗号分割key和agrv 

    十五、Redis两种持久化方式

    1,rds(默认)
    快照模式,定时保存。如果重启有可能会丢失部分数据

    配置信息:

    强制持久化命令:save(客户端阻塞)或者bgsave(会开启一个进程执行)

    2,aof

    来一条命令则保存一次,aof文件保存的是文本协议

    开启方式 

    ①注销save

    ②appendonly设置为yes

     

    三种写入模式:

    #appendfsync always:来一条保存一条,强制保存到硬盘【安全性高,性能差】
    appendfsync everysec:1秒强制保存到硬盘一次【折中方案】
    #appendfsync no:来一条保存一条,只保存到系统的缓冲期,至于保存到硬盘是有系统决定【安全性差,性能高】

    十六、搭建Redis主-备(mster-slave)

    1,配置mster-slave
    配置文件# slaveof <masterip> <masterport>配置主机地址
    例如:slaveof 192.168.1.102 6379
    如果主redis有密码需要配置# masterauth <master-password>
    info 查看redis信息

    注:一旦redis服务器被设置为slave,则该redis不能写入了。只能从master中写入

    2,c#中使用

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using StackExchange.Redis;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var con= ConnectionMultiplexer.Connect("192.168.1.102:6379,192.168.1.103:6379");
                var db = con.GetDatabase();
    
                db.StringAppendAsync("password", "123456");//会使用主redis
                var p = db.StringGetAsync("password").Result;//会使用备redis
    
                Console.WriteLine(p);
                Console.ReadKey();
            }
        }
    }
    c#端调用

    注:如果主redis挂了,则写入会失败。可以查询

    十七、搭建Redis主-备(mster-slave)+哨兵(sentinel)

    sentinel监视redis主备,当主redis挂了,sentinel自动让一个slave变为master。
    当原来master恢复之后,原来master恢复已经成为slave了

    1,架构sentinel

    例如在一台centos上建立三个哨兵

    这三个哨兵会监视一个master,当有2个哨兵主观认为master挂了,则sentinel自动让一个slave变为master

    主redis:192.168.1.102:6379

    备redis:192.168.1.103:6379

    主redis未挂时,备redis的状态:

    主redis挂了,备redis的状态:

    sentinel案例下载:https://pan.baidu.com/s/1ggvCu47

    1,配置具体的sentinel

    ①拷贝redis-sentinel程序和sentinel.conf配置文件到s1、s2、s3文件中

    ②配置sentinel.conf

    port 26379  #设置sentinel的端口

    protected-mode no #将protected-mode设置为no

    sentinel monitor <master-name> <ip> <redis-port> <quorum> #设置监控的master

    master-name:设置主redis 的名称,随便写

    ip:主redis 的ip地址

    redis-port:主redis的端口号

    quorum:当主观认为master挂掉的哨兵达到2个时,则客观认为master挂了。需要切换master了

    例:sentinel monitor mymaster 192.168.1.102 6379 2

    sentinel auth-pass <master-name> <password> #如果master设置了密码,则需要配置master的密码

    例:sentinel auth-pass mymaster 123456

    sentinel down-after-milliseconds mymaster 30000 #master30秒没响应,则主观认为master挂了

    ③启动sentinel

    进入放置sentinel的文件夹

    执行命令./redis-sentinel ./sentinel.conf 启动sentinel

    注意:在同一系统下运行多个sentinel,sentinel的端口号不要重复

    十八、 web监控【redislive】

    python写的一个web监控

    1,安装redislive

    ①首先需要安装pip(python的安装工具包pip-9.0.1.tar.gz)【相当于nuget】
    下载地址:https://pypi.python.org/pypi/pip

    网速慢可以下载:https://pan.baidu.com/s/1qZezffm

    拷贝到centos的usr文件下,解压,进入解压文件中
    python setup.py install 安装

    ②安装tornado【相当于iis】
    pip install tornado --upgrade

    ③安装redis.py 【python redis驱动,相当于.net StackExchange】
    pip install redis

    ④安装python-dateutil 【类库,相当于dll】
    pip install python-dateutil --upgrade 强制更新到最新

    ⑤获取redislive的源代码
    https://github.com/nkrode/RedisLive
    解压放到centos的usr文件下。进入文件夹
    将redis-live.conf.example改为redis-live.conf

    redis-live.conf配置文件解析:
    RedisServers:监控的RedisServers的服务器地址和端口
    DataStoreType:存储类型(redis或者Sqlite存储,默认redis)
    RedisStatsServer:配置存储redis的服务器地址和端口
    {
        "RedisServers":
        [ 
            {
                  "server": "192.168.1.103",
                  "port" : 6379
            }        
        ],
    
        "DataStoreType" : "redis",
    
        "RedisStatsServer":
        {
            "server" : "192.168.1.103",
            "port" : 6379
        },
        
        "SqliteStatsStore" :
        {
            "path":  "to your sql lite file"
        }
    }
    配置案例

    ⑥开启监控脚本:./redis-monitor.py --duration=120【duration=120 默认采集二分钟】

    ⑦开启web站点:./redis-live.py

    ⑧访问
    http://localhost:8888/index.html
    http://192.168.1.103:8888/index.html

    十九、 搭建cluster(集群)

    参考文档:http://www.redis.cn/topics/cluster-tutorial.html

    可能出现各种依赖问题请参考:
    https://www.cnblogs.com/carryping/p/7447823.html
    http://blog.csdn.net/Hello_World_QWP/article/details/78260684
    http://blog.csdn.net/hello_world_qwp/article/details/78261618

    1,开启cluster(集群)模式
    配置文件:
    cluster-enabled yes 开启集群
    cluster-config-file nodes-6379.conf 集群节点文件

    2,redis src下找到redis-trib.rb
    ①安装ruby环境:yum install ruby

    ②ruby的redis驱动:gem install redis
    ③rubygems安装:yum install -y rubygems

    ④通过第三方工具进行安装
    ./redis-trib.rb create --replicas 1 192.168.1.103:6379 192.168.1.103:6380 192.168.1.103:6381 192.168.1.103:6382

    cluster nodes 查看集群
    redis-cli -c 使用这种redis-cli的开启方式

    3,c#驱动访问方式:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using StackExchange.Redis;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var con= ConnectionMultiplexer.Connect("192.168.1.103:6379,192.168.1.103:6380,192.168.1.103:6381,192.168.1.103:6382");
                var db = con.GetDatabase();
    
                db.StringSet("cc", "123456");//会使用主redis
                var p = db.StringGetAsync("cc").Result;//会使用备redis
    
                Console.WriteLine(p);
                Console.ReadKey();
            }
        }
    }
    View Code

    升级完ruby需要重启

    注意:

    >>>创建群集
    ***错误:集群创建的配置无效。
    *** Redis群集至少需要3个主节点。
    ***对于每个节点3个节点和1个副本,这是不可能的。
    ***至少需要6个节点。

  • 相关阅读:
    selenium使用
    爬取梨视频
    django实现事务
    django admin模块使用
    跨域问题和django中实现跨域
    Java多线程Condition定点通知
    Java创建线程四种方式
    JVM之JVM体系结构
    Java线程状态
    Java正则表达式解析网页源码
  • 原文地址:https://www.cnblogs.com/zd1994/p/8321509.html
Copyright © 2020-2023  润新知