Redis心得

redis优势

  • 存储结构:5种;
    字符。散列,列表,集合,有序集合

  • 功能
    1.可以为每个key设置超时时间;
    2.通过列表类型实现分布式队列操作
    3.支持发布订阅的消息模式

  • 简单(丰富命令)
    1.提供很多命令与redis交互

应用场景

1.数据缓存(商品数量,热点数据)
2.单点登录
3.秒杀抢购
4.网站访问排名
5.应用模块开发

redis 安装

  • 安装教程
    1.下载安装包
    2.解压缩
    3.make
    4.make test 测试编译状态
    5.make install prefix=路劲–指定路径

  • 启动关闭连接
    ./redis-server redis.conf 启动
    ./redis-cli shutdown 关闭
    ./redis-cli -h 127.0.0.1 -p 6379 远程连接

  • redis其他命令
    redis-server 启动服务
    redis-cli redis控制台
    redis-benchmark 性能测试工具
    redis-check-aof aof文件进行检测工具
    redis check-dump rdb文件检查工具
    redis-sentinel sentinel服务器配置

  • 后台方式启动
    修改redis.conf的 daemonize yes

多数据支持

默认支持16个数据库,可以理解为一个命名空间,跟关系型数据库不一样的点
1.不支持自定义数据库名次
2.每个数据库不能单独设置授权
3.每个数据库之间不是完全隔离的,可以通过flushall命令清空redis实力面的所有数据库的数据。
通过select dbid选择不同的数据库命名空间 dbid取值范围0-15

使用入门

1.获得一个符合匹配规则的键名列表
keys pattern 模糊?/*/
2.判断一个键是否存在
exists key
3.获取键的类型
type key

各种数据结构

  • 字符
    1.字符类型默认存储最大容量512m。
    2.key的设计:
    对象类型:对象id:对象属性:对象子属性
    短信重发–设置超时时间
    3.操作
    get key 取值,set key value 赋值,incr key 递增数字; incryby key 5 增加具体数量
    decr key 原子递减,append 住家字符串, strlen获取key对应value的长度。
    mget key key 获取多个值,mset k v k v 设置多个键值对,setnx判断 key是否已存 在。

  • 列表
    1.操作
    lpush 、rpush key [value,...] 分别从左右push数据, lpop、rpop 移除并返回数据----可以实现分布式队列,llen key 列表长度, lrange key start stop 取范围---索引可以为负数,-1表示从右边第一个
    lrem key count value lset key index value修改值

  • 散列 hash
    hash key value 不支持数据类型的嵌套 比较适合存储对象。
    1.操作
    hset key field value,hget key field 赋值取值 hmset key[field value ] hmget key[field]批量赋值取值 hgetall key获取hash的所有信息,hexists key field 是否存在、hsetnx 存在返回0否则返回1、hdel key [field] 删除一个或多个字段

  • 集合
    set跟list不一样?不可重复。
    1.操作
    sadd key [menber]---批量插入集合;srem key member 删除原元素;smembers key获得所有数据;sdiff 多个集合进行差集运算;sunion 对多个集合执行并集;sinter对多个集合执行交集运算

  • 有序集合
    1.操作
    zadd key [score member] score 排序 ,批量插入有序集合 ;zrange key start stop [withoutscores] 获取范围元素 排序(0<9<A<Z<a<z)

redis 的事务处理

multi开启事务
exec提交事务

过期时间

expire key seconds 过期时间设置
ttl key 获取key’ 的过期时间

发布订阅

publish channel message
subscribe channel […]
缺点:不稳定,性能消耗大,基本不用

redis分片

codis twmproxy

redis分布式锁

  • 多进程架构:
    1.资源共享竞争
    2.数据的安全

  • 分布式锁的解决方案
    1、怎么获取锁
    数据库 lock 唯一约束
    delete释放锁,非重入锁。
    2.zookeeper
    利用zookeeper的唯一节点特性或者有序临时节点特性获得最小节点作为锁. zookeeper 的实现相对简单,通过curator客户端,已经对锁的操作进行了封装,原理如下在这里插入图片描述

  • zookeeper的优势
    1.可靠性高、实现简单
    2.zookeeper因为临时节点的特性,如果因为其他客户端因为异常和zookeeper连接中断了,那么节点会被删除,意味着锁会被自动释放
    3.zookeeper本身提供了一套很好的集群方案,比较稳定
    4.释放锁操作,会有watch通知机制,也就是服务器端会主动发送消息给客户端这个锁已经被释放了

  • redis实现
    redis中有一个setNx命令,这个命令只有在key不存在的情况下为key设置值。所以可以利用这个特性来实现分布式锁的操作
    代码示例:
    在这里插入图片描述
    在这里插入图片描述

  • redis 多路复用
    linux的内核会把所有外部设备都看作一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个 file descriptor(文件描述符)。对于一个socket的读写也会有响应的描述符,称为socketfd(socket 描述符)。而IO多路复用是指内核一旦发现进程指定的一个或者多个文件描述符IO条件准备好以后就通知该进程
    IO多路复用又称为事件驱动,操作系统提供了一个功能,当某个socket可读或者可写的时候,它会给一个通知。当配合非阻塞socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据。操作系统的功能通过select/pool/epoll/kqueue之类的系统调用函数来使用,这些函数可以同时监视多个描述符的读写就绪情况,这样多个描述符的I/O操作都能在一个线程内并发交替完成,这就叫I/O多路复用,这里的复用指的是同一个线程
    多路复用的优势在于用户可以在一个线程内同时处理多个socket的 io请求。达到同一个线程同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到目的在这里插入图片描述

  • lua语言
    优势:
    1.减少网络开销 2.原子操作3.复用性

  • lua的安装过程
    1.解压缩
    2.cd目录,make
    3.make install

  • Redis与Lua
    在Lua脚本中调用Redis命令,可以使用redis.call函数调用。比如我们调用string类型的命令
    redis.call(‘set’,’hello’,’world’)
    redis.call 函数的返回值就是redis命令的执行结果。前面我们介绍过redis的5中类型的数据返回的值的类型也都不一样。redis.call函数会将这5种类型的返回值转化对应的Lua的数据类型

  • 从Lua脚本中获得返回值
    在很多情况下我们都需要脚本可以有返回值,在脚本中可以使用return 语句将值返回给redis客户端,通过return语句来执行,如果没有执行return,默认返回为nil。

  • 在redis中执行lua脚本
    Redis提供了EVAL命令可以使开发者像调用其他Redis内置命令一样调用脚本。
    [EVAL] [脚本内容] [key参数的数量] [key …] [arg …]
    可以通过key和arg这两个参数向脚本中传递数据,他们的值可以在脚本中分别使用KEYS和ARGV 这两个类型的全局变量访问。比如我们通过脚本实现一个set命令,通过在redis客户端中调用,那么执行的语句是:
    lua脚本的内容为:return redis.call(‘set’,KEYS[1],ARGV[1]) //KEYS和ARGV必须大写
    eval "return redis.call('set',KEYS[1],ARGV[1])" 1 hello world
    EVAL命令是根据 key参数的数量-也就是上面例子中的1来将后面所有参数分别存入脚本中KEYS和ARGV两个表类型的全局变量。当脚本不需要任何参数时也不能省略这个参数。如果没有参数则为0
    eval "return redis.call(‘get’,’hello’)" 0

  • EVALSHA命令
    考虑到我们通过eval执行lua脚本,脚本比较长的情况下,每次调用脚本都需要把整个脚本传给redis,比较占用带宽。为了解决这个问题,redis提供了EVALSHA命令允许开发者通过脚本内容的SHA1摘要来执行脚本。该命令的用法和EVAL一样,只不过是将脚本内容替换成脚本内容的SHA1摘要
    1.Redis在执行EVAL命令时会计算脚本的SHA1摘要并记录在脚本缓存中
    2.执行EVALSHA命令时Redis会根据提供的摘要从脚本缓存中查找对应的脚本内容,如果找到了就执行脚本,否则返回“NOSCRIPT No matching script,Please use EVAL”

    通过以下案例来演示EVALSHA命令的效果
    script load "return redis.call('get','hello')" 将脚本加入缓存并生成sha1命令
    evalsha "a5a402e90df3eaeca2ff03d56d99982e05cf6574" 0
    我们在调用eval命令之前,先执行evalsha命令,如果提示脚本不存在,则再调用eval命令

  • lua脚本实战
    实现一个针对某个手机号的访问频次, 以下是lua脚本,保存为phone_limit.lua
    local num=redis.call('incr',KEYS[1]) if tonumber(num)==1 then redis.call('expire',KEYS[1],ARGV[1]) return 1 elseif tonumber(num)>tonumber(ARGV[2]) then return 0 else return 1 end
    通过如下命令调用
    ./redis-cli --eval phone_limit.lua rate.limiting:13700000000 , 10 3
    语法为 ./redis-cli –eval [lua脚本] [key…]空格,空格[args…]

  • 脚本的原子性
    redis的脚本执行是原子的,即脚本执行期间Redis不会执行其他命令。所有的命令必须等待脚本执行完以后才能执行。为了防止某个脚本执行时间过程导致Redis无法提供服务。Redis提供了lua-time-limit参数限制脚本的最长运行时间。默认是5秒钟。
    当脚本运行时间超过这个限制后,Redis将开始接受其他命令但不会执行(以确保脚本的原子性),而是返回BUSY的错误

  • 实践操作
    打开两个客户端窗口
    在第一个窗口中执行lua脚本的死循环
    eval “while true do end” 0
    打开两个客户端窗口
    在第一个窗口中执行lua脚本的死循环
    eval “while true do end” 0

    最后第二个窗口的运行结果是Busy, 可以通过script kill命令终止正在执行的脚本。如果当前执行的lua脚本对redis的数据进行了修改,比如(set)操作,那么script kill命令没办法终止脚本的运行,因为要保证lua脚本的原子性。如果执行一部分终止了,就违背了这一个原则
    在这种情况下,只能通过 shutdown nosave命令强行终止

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值