目录

. Redis 简介
. Redis安装配置
. 编程使用Redis
. 使用Lua脚本

1. Redis 简介

0x1: Redis是什么

Redis是一款Nosql类型的基于key-value的高速缓存系统,

从架构上看,redis有3种特性

. key value store
是一个以key-value形式存储的数据库,定位直指MySQL,用来作为唯一的存储系统 . memory cache
是一个把数据存储在内存中的高速缓存,用来在应用和数据库间提供缓冲,替代memcachd . data structrue server
把它支持对复杂数据结构的高速操作作为卖点,提供某些特殊业务场景的计算和展现需求。比如排行榜应用,Top 10之类的

在redis的键值的"值"中,它所支持的数据结构有:

. String
) 常用命令
   set、get、decr、incr、mget等
   ) 应用场景
   String是最常用的一种数据类型,普通的key/value存储都可以归为此类
   ) 实现方式
   String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr、decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int . Hash
) 常用命令
   hget、hset、hgetall等
   ) 应用场景
) 实现方式
   Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现
3.1) 这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap
3.2) 当成员数量增大时会自动转成真正的HashMap,此时encoding为ht . List
) 常用命令
   lpush、rpush、lpop、rpop、lrange等
   ) 应用场景
   Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现
   ) 实现方式
   Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构 . Set
) 常用命令
   sadd、spop、smembers、sunion等
   ) 应用场景
   Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集
合内的重要接口,这个也是list所不能提供的
   ) 实现方式:
   set的内部实现是一个value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因 . Sorted set
) 常用命令
   zadd、zrange、zrem、zcard等
   ) 使用场景
   Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集
合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的
   ) 实现方式
   Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获
得比较高的查找效率,并且在实现上比较简单

Redis内部使用一个redisObject对象来表示所有的key和value

. type
代表一个value对象具体是何种数据类型
. encoding
不同数据类型在redis内部的存储方式,比如:type=string代表value存储的是一个普通字符串,那么对应的encoding可以是raw或者是int,如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的,当然前提是这个
字符串本身可以用数值表示,比如:"" ""这样的字符串
. ptr
数据指针
. vm
只有打开了Redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的

我们可以发现Redis使用redisObject来表示所有的key/value数据是比较浪费内存的,当然这些内存管理成本的付出主要也是为了给Redis不同数据类型提供一个统一的管理接口

0x2: Redis支持的指令集

Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些command可以在Linux终端使用(redis-cli)。也可以在编程时通过API方式使用,比如使用Redis 的Java语言包

. 连接操作相关的命令
) QUIT: 关闭连接(connection)
) AUTH: 简单密码认证 . 适合全体类型的命令
) EXISTS(key) 确认一个 key 是否存在
) DEL(key) 删除一个 key
) TYPE(key) 返回值的类型
) KEYS(pattern) 返回满足给定 pattern 的所有 key
) RANDOMKEY:随机返回 key 空间的一个key
) RENAME(oldname, newname) 将 key 由 oldname 重命名为 newname,若 newname 存在则删除 newname 表示的 key
) DBSIZE:返回当前数据库中 key 的数目
) EXPIRE(key,ttl) 设定一个 key 的生存时间 ttl(s)
) TTL(key) 获得一个 key 的活动时间
) SELECT(index) 按索引查询;
) MOVE(key, dbindex) 将当前数据库中的 key 转移到有 dbindex 索引的数据库
) FLUSHDB:删除当前选择数据库中的所有 key
) FLUSHALL:删除所有数据库中的所有 key . 自定义扩展指令相关的指令
) EVAL: EVAL script numkeys key [key ...] arg [arg ...]
EVAL 和 EVALSHA 命令是从 Redis 2.6. 版本开始的,使用内置的 Lua 解释器,可以对 Lua 脚本进行求值 、对 STRING 操作的命令
) SET(key, value) 给数据库中名称为 key 的 string 赋予值 value
) GET(key) 返回数据库中名称为 key 的 string 的 value
) GETSET(key, value) 给名称为 key 的 string 赋予上一次的value
) MGET(key1, key2,…, key{$n}) 返回库中多个 string(它们的名称为key1,key2...)的value
) SETNX(key, value) 如果不存在名称为 key 的 string,则向库中添加 string,名称为 key,值为 value;
) SETEX(key, time, value) 向库中添加 string(名称为key,值为value)同时,设定过期时间time;
) MSET(key1, value1, key2, value2,…key{$n}, value{$n}) 同时给多个 string 赋值,名称为 key{$i} 的 string 赋值 value{$i};
) MSETNX(key1, value1, key2, value2,…key{$n}, value{$n}) 如果所有名称为 key{$i} 的 string 都不存在,则向库中添加 string,名称 key{$i} 赋值为 value{$i};
) INCR(key) 名称为 key 的 string 增1操作;
) INCRBY(key, integer) 名称为 key 的 string 增加 integer;
) DECR(key) 名称为 key 的 string 减1操作;
) DECRBY(key, integer) 名称为 key 的 string 减少 integer;
) APPEND(key, value) 名称为 key的 string 的值附加 value;
) SUBSTR(key, start, end) 返回名称为 key 的 string 的 value 的子串 、对无索引序列 LIST 操作的命令
) RPUSH(key, value) 在名称为 key 的 list 尾添加一个值为 value 的元素;
) LPUSH(key, value) 在名称为 key 的 list 头添加一个值为 value 的 元素;
) LLEN(key) 返回名称为 key 的 list 的长度;
) LRANGE(key, start, end) 返回名称为 key 的 list 中 start 至 end 之间的元素(下标从0开始,下同)
) LTRIM(key, start, end) 截取名称为 key 的 list,保留 start 至 end 之间的元素;
) LINDEX(key, index) 返回名称为 key 的 list 中 index 位置的元素;
) LSET(key, index, value) 给名称为 key 的 list 中 index 位置的元素赋值为 value;
) LREM(key, count, value) 删除 count 个名称为 key 的 list 中值为value的元素。count 为0,删除所有值为 value 的元素,count>0从 头至尾删除 count 个值为 value 的元素,count<0从尾到头删除|count|个值为value的元素;
) LPOP(key) 返回并删除名称为key的list中的首元素;
) RPOP(key) 返回并删除名称为key的list中的尾元素;
) BLPOP(key1, key2,… key{$n}, timeout) LPOP 命令的 block 版本。即当 timeout 为0时,若遇到名称为 key{$i} 的 list 不存在或该 list 为空,则命令结束。如果 timeout>,则遇到上述情况时,等待 timeout 秒,如果问题没有解决,则对 key{$i}+ 开始的 list 执行 pop 操作;
) BRPOP(key1, key2,… key{$n}, timeout) RPOP 的 block 版本。参考上一命令;
) RPOPLPUSH(srckey, dstkey) 返回并删除名称为 srckey 的 list 的尾元素,并将该元素添加到名称为 dstkey 的 list 的头部。 、对有索引无序集合 SET 操作的命令
) SADD(key, member) 向名称为 key 的 set 中添加元素 member;
) SREM(key, member) 删除名称为 key 的 set 中的元素 member;
) SPOP(key) 随机返回并删除名称为 key 的 set 中一个元素;
) SMOVE(srckey, dstkey, member) 将 member 元素从名称为 srckey 的集合移到名称为 dstkey 的集合;
) SCARD(key) 返回名称为 key 的 set 的基数;
) SISMEMBER(key, member) 测试 member 是否是名称为 key 的 set 的元素;
) SINTER(key1, key2,…key{$n}) 求交集;
) SINTERSTORE(dstkey, key1, key2,…key{$n}) 求交集并将交集保存到 dstkey 的集合;
) SUNION(key1, key2,…key{$n}) 求并集;
) SUNIONSTORE(dstkey, key1, key2,…key{$n}) 求并集并将并集保存到 dstkey 的集合;
) SDIFF(key1, key2,…key{$n}) 求差集;
) SDIFFSTORE(dstkey, key1, key2,…key{$n}) 求差集并将差集保存到 dstkey 的集合;
) SMEMBERS(key) 返回名称为 key 的 set 的所有元素;
) SRANDMEMBER(key) 随机返回名称为 key 的 set 的一个元素。 、持久化
) SAVE:将数据同步保存到磁盘;
) BGSAVE:将数据异步保存到磁盘;
) LASTSAVE:返回上次成功将数据保存到磁盘的 UNIX 时戳;
) SHUNDOWN:将数据同步保存到磁盘,然后关闭服务 、远程服务控制
) INFO:提供服务器的信息和统计;
) MONITOR:实时转储收到的请求;
) SLAVEOF:改变复制策略设置;
) CONFIG:在运行时配置 Redis 服务器

0x3: 配置密码登录

关于密码验证

. 如果redis监听回环IP之外的地址 任何人都可以读取其信息,所以安全问题需要考虑,即redis是默认未授权可任意访问的
. 即使显式设置了密码验证,但是redis服务器的login响应速度极快,因此官方文件中提醒设置比较复杂的密码,防止机器破解

redis配置密码

. vim /etc/redis.conf
. requirepass littlehann
//littlehann是设置的密码
. 重启redis
sudo service redis restart
#或者
sudo service redis stop
sudo redis-server /etc/redis.conf . 尝试登录redis,在没有进行身份认证的情况下
(error) ERR operation not permitted . 进行身份认证
redis-cli -h 127.0.0.1 -p -a littlehann
#或者
redis-cli
auth littlehann

除了使用这种修改配置文件并重启的方式进行redis密码配置之外,还可以通过指令,动态地对redis进行密码配置(重启后失效)

. config set requirepass my_redis
. config get requirepass
//无需重启redis,之前配置的老密码会失效(只在本次启动声明周期内有效)

Relevant Link:

http://try.redis.io/
http://www.redis.cn/
http://jandyu.diandian.com/post/2012-03-15/16145594
http://tech.it168.com/a2011/0818/1234/000001234478_all.shtml
http://hedatou.com/archives/introduction_to_redis.html
http://blog.csdn.net/tianmohust/article/details/7739739
http://www.redis.cn/commands.html
http://www.lvtao.net/content/book/redis.htm
http://blog.csdn.net/zyz511919766/article/details/4226821

2. Redis安装配置

0x1: 主程序安装

cd /usr/local
wget http://download.redis.io/releases/redis-2.8.13.tar.gz
tar xzf redis-2.8..tar.gz
cd redis-2.8.
make
/*make命令执行完成后,会在当前src目录(/usr/local/redis-2.8.13/src)下生成本个可执行文件如下:
1. redis-server:Redis服务器的daemon启动程序
2. redis-cli:Redis命令行操作工具。当然,你也可以用telnet根据其纯文本协议来操作
3. redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能
4. redis-stat:Redis状态检测工具,可以检测Redis当前状态参数及延迟状况
*/

0x2: 命令测试

//启动server
./redis-server
//测试benchmark
./redis-benchmark
//使用内置的客户端连接Redis
./redis-cli
127.0.0.1:> set foo bar
OK
127.0.0.1:> get foo
"bar"
127.0.0.1:>

0x3: 运行Redis所需要的内核参数优化

/*
1. overcommit_memory
指定了内核针对内存分配的策略,其值可以是0、1、2。
0: 表示内核将检查是否有足够的可用内存供应用进程使用
1) 如果有足够的可用内存,内存申请允许
2) 否则,内存申请失败,并把错误返回给应用进程
1: 表示内核允许分配所有的物理内存,而不管当前的内存状态如何
2: 表示内核允许分配超过所有物理内存和交换空间总和的内存
*/
vim /etc/sysctl.conf
//添加
vm.overcommit_memory=
//刷新配置使之生效
sysctl vm.overcommit_memory=

0x4: Redis配置文件

vim /usr/local/redis-2.8./redis.conf
//1. 开启守护进程
daemonize yes
//2. 每隔5秒输出一行监控信息(默认)
daemonize no //3. 减小改变次数,这个参数可以根据情况进行指定
save //4. 分配256M内存
maxmemory //5. pid文件位置
pidfile /var/run/redis.pid //6. 监听的端口号
port //7. 请求超时时间
timeout //8. log信息级别
loglevel notice //9. 开启数据库的数量
databases /*
10. 保存快照的频率
1) 第一个*表示多长时间
2) 第二个*表示执行多少次写操作
在一定时间内执行一定数量的写操作时,自动保存快照。可设置多个条件
*/
save * * //11. 是否使用压缩
rdbcompression yese //12. 数据快照文件名(只是文件名,不包括目录)
dbfilename dump.rdb //13. 数据快照的保存目录(这个是目录)
dir ./ //14. 是否开启appendonlylog,开启的话每次写操作会记一条log,这会提高数据抗风险能力,但影响效率
appendonly no /*
15. appendonlylog如何同步到磁盘
1) always: 每次写都强制调用fsync
2) everysec: 每秒启用一次fsync
3) no: 不调用fsync等待系统自己同步
*/
appendfsync everysec

配置好保存,重启redis,就可以正常启动了,和mysql一样,redis是基于socket监听端口的方式提供服务的,我们可以使用telnet、或者socket方式进行连接

Relevant Link:

http://www.redis.cn/documentation.html
http://www.redis.cn/download.html
http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2011/0406/7873.html

3. 编程使用Redis

0x1: PHP连接Redis

使用php连接redis需要安装php的扩展

下载redis扩展源代码
http://pecl.php.net/package/redis
解压缩后进行编译
phpize
./configure --enable-hello
make
关于php扩展的原理以及编译过程请参阅另一篇文章
http://www.cnblogs.com/LittleHann/p/3562259.html
将编译好的.so文件复制到php的扩展目录中
cp redis.so /usr/lib/php/modules/
修改php.ini中的extension,增加redis扩展的自动启动
重启apache即可

Code

<?php
$redis = new redis();
$result = $redis->connect('192.168.207.128', );
var_dump($result); //结果:bool(true) $result = $redis->set('name',"LittleHann");
var_dump($result); //结果:bool(true) $result = $redis->get('name');
var_dump($result); //结果:LittleHann $redis->delete('name');
var_dump($result); //结果:bool(true)
?>

Relevant Link:

https://github.com/nrk/predis
https://github.com/Shumkov/Rediska
https://github.com/jdp/redisent
http://www.cnblogs.com/ikodota/archive/2012/03/05/php_redis_cn.html
http://blog.51yip.com/cache/1439.html
http://www.cnblogs.com/jackluo/p/3412670.html

0x2: Java连接Redis

Relevant Link:

http://outofmemory.cn/code-snippet/128/java-usage-redis-jiandan-usage
http://www.cnblogs.com/edisonfeng/p/3571870.html

4. 使用Lua脚本(Redis将lua引擎静态编译包含使redis具备解析lua脚本的能力)

0x1: 初始化 Lua 环境

在初始化 Redis 服务器时, 对 Lua 环境的初始化也会一并进行,为了让 Lua 环境符合 Redis 脚本功能的需求, Redis 对 Lua 环境进行了一系列的修改, 包括添加函数库、更换随机函数、保护全局变量, 等等
整个初始化 Lua 环境的步骤如下

. 调用 lua_open 函数,创建一个新的 Lua 环境
. 载入指定的 Lua 函数库,包括:
) 基础库(base lib)
) 表格库(table lib)
) 字符串库(string lib)
) 数学库(math lib)
) 调试库(debug lib)
) 用于处理 JSON 对象的 cjson 库
) 在 Lua 值和 C 结构(struct)之间进行转换的 struct 库
) 处理 MessagePack 数据的 cmsgpack 库
. 屏蔽一些可能对 Lua 环境产生安全问题的函数,比如 loadfile
. 创建一个 Redis 字典,保存 Lua 脚本,并在复制(replication)脚本时使用。字典的键为 SHA1 校验和,字典的值为 Lua 脚本
. 创建一个 redis 全局表格到 Lua 环境,表格中包含了各种对 Redis 进行操作的函数,包括
) 用于执行 Redis 命令的 redis.call 和 redis.pcall 函数
) 用于发送日志(log)的 redis.log 函数,以及相应的日志级别(level)
redis.LOG_DEBUG
redis.LOG_VERBOSE
redis.LOG_NOTICE
redis.LOG_WARNING
) 用于计算 SHA1 校验和的 redis.sha1hex 函数
) 用于返回错误信息的 redis.error_reply 函数和 redis.status_reply 函数
. 用 Redis 自己定义的随机生成函数,替换 math 表原有的 math.random 函数和 math.randomseed 函数,新的函数具有这样的性质:每次执行 Lua 脚本时,除非显式地调用 math.randomseed ,否则 math.random 生成的伪随机数序列总是相同的
. 创建一个对 Redis 多批量回复(multi bulk reply)进行排序的辅助函数
. 对 Lua 环境中的全局变量进行保护,以免被传入的脚本修改
. 因为 Redis 命令必须通过客户端来执行,所以需要在服务器状态中创建一个无网络连接的伪客户端(fake client),专门用于执行 Lua 脚本中包含的 Redis 命令:当 Lua 脚本需要执行 Redis 命令时,它通过伪客户端来向服务器发送命令请求,服务器在执行完命令之后,将结果返回给伪客户端,而伪客户端又转而将命令结果返回给 Lua 脚本
. 将 Lua 环境的指针记录到 Redis 服务器的全局状态中,等候 Redis 的调用

这些步骤都执行完之后, Redis 就可以使用 Lua 环境来处理脚本了

0x2: 脚本的安全性

Redis 对 Lua 环境所能执行的脚本做了一个严格的限制 —— 所有脚本都必须是无副作用的纯函数(pure function)
为此,Redis 对 Lua 环境做了一些列相应的措施

. 不提供访问系统状态状态的库(比如系统时间库)
. 禁止使用 loadfile 函数
. 如果脚本在执行带有随机性质的命令(比如 RANDOMKEY ),或者带有副作用的命令(比如 TIME )之后,试图执行一个写入命令(比如 SET ),那么 Redis 将阻止这个脚本继续运行,并返回一个错误
. 如果脚本执行了带有随机性质的读命令(比如 SMEMBERS ),那么在脚本的输出返回给 Redis 之前,会先被执行一个自动的字典序排序,从而确保输出结果是有序的
. 用 Redis 自己定义的随机生成函数,替换 Lua 环境中 math 表原有的 math.random 函数和 math.randomseed 函数,新的函数具有这样的性质:每次执行 Lua 脚本时,除非显式地调用 math.randomseed ,否则 math.random 生成的伪随机数序列总是相同的

经过这一系列的调整之后, Redis 可以保证被执行的脚本

. 无副作用
. 没有有害的随机性
. 对于同样的输入参数和数据集,总是产生相同的写入命令

0x3: 脚本的执行

在脚本环境的初始化工作完成以后, Redis 就可以通过 EVAL 命令或 EVALSHA 命令执行 Lua 脚本了

1. EVAL(对输入的脚本代码体进行求值)

EVAL "return 'hello world'" 

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZYAAAAlCAIAAADus1iuAAAFIklEQVR4nO2c2bmkIBCFb06mQzDmQiyGYhwzDy7UCkVrq919/m8e5tIWVQgc2fTvzyHleRoHkjCM07ySE0nkV3mJuzX7xTR3k2V8jJyMoIdxmqdpMhLN7M0831dMA+PKPcuct9LRq1I10SySfWXxVBz5UeqmQJNJqi6RG9KY9a2j11NfNpVGuxuX7FQxt5+YIzPRcc6vtBuDwzBOsQLq4OkN1cUsie5N9iqOJzq9w/Tec+dJBmb0tK3qxOP39A3c5hispHx1BcRFvpkP2g4Av8kw5n3kdoqedPk+R8IAAD/MNvi/Xk0gYQw5ZwtOZQEAAAAAAAAAXER4Glu22cj1ZuJltL3fsLR5N+ZecHWDOOVW9XknMirtodko3AMMhrG5bRyN0za3HdmUtQ16TkOY6wWQ5eIeR75jYs+37XgLT3nm29gdCzDL1a9vCl64IMZd9To2ReFepah4N04a6WMuwYqL9qNHED4K9ZfylHO1DQzjRM/KqKM7B1qTMEiZHcsp4kDO0Pj5O3Fa5imXbBp1z4qcxpj5Hrxdoih2ceVhMK5nU0mAhJn8qoRF+9FDiEpYynNOPW1AdoszJUxYr0LBPIYd7FZt82qebRmw76o+sLqVqEMknJZWknlei7cS8QkSRs9TztRrdQSakyg7K4jKkyUED5LKRmeZO7O0oISFjraagjKNQ/WYtLyfNe/qBO/LEvZaP7qPWF9dxy0d5bEOUHsTyUj3qUvYWjU6MR5n25wOlNYSiKoe9UTSM9+yoCeqtffo8QfvYUn1WY0Hi/sTzrgO4yTDJD5Zt5GtqCZhhtSUaXdvzI65F2dMwthdrNST8UhXlSA7SKf3cwZMr/WjG4lI2P5nz9BGFty3NS5uxSmmXfO8DCrWocucU3AITPJxzXe11frDmzsPifYKW9VYf7FKJJxVxF6MbthKnHr27H73/5wkYVYXLX/ROW1cwtw8X5jimOZ+nCEJE3n6t3HLebPXQyI5+nGegxXvp0iY1RGO5/pGAhJWbm1MwvQ6WMs20IWMdr8PssfXRmE8ztgozC1Cv7n1QOUl0r9VJMyObAlLDoJIfW7N9AQJU6NuPml0l/rqE0lvJP+ahGlzP86ohAVD2qoiT9M2Jx46yn7Qe5wvHIXpHbTGnN/+/WQJM37qmsPrOAPmtTjpyr1zJU2sToTosPfQRHL1KR3LynyThDkhPU7CvHxOHYUtP49jHoeU9yqpjcJiEnb6KOxL18KcdDGZ8vVL2rL+Xl1jclyvO37c2t1JicVpmLM41aiNx0lqfrvSN9cKpkvUsdzT2KiappIPv3T56x0SJjyl7Kt3uZCPVC+RMD9OuwJkYnQtbHt4rKNevSinmqyVWdX7SRLm96PHwYdXRQasMfVCQ8LM/SYnT5qm50yyhetM6bSLP5XaeXpxWuZs0CIbj1Qh/TkRx9xqGXaJYrglUgtr0nPKM92GMKskgvcoNDPcw5WVybfVLpIwP849UDN6VceteNgiJHuaaXN39ON5b346qQenHwEAAAAAAAAAAAAAAAAAABwnfAjE3D07sqV2nLb3h28QAwA6Ue849J5jC71Edi2NE1L0cEE+8rkFAMDtQMIgYQB8MLaE/cbXSCBhAHwf5MS58/YV7/MhCYu+gSHfchme+jUSAMBDMXWLq5Z8A/y892DJ29rkre3ae7A3fY0EAPBQ8DUSAMAHg6+RAAA+GHyNBADwweBrJAAAAAAAAAAAAAAAAAAAAO/hn/UPAAA+A0gY+Hb+Awto7c6d0H7eAAAAAElFTkSuQmCC" alt="" />

由于redis替换了lua中的基本库全局变量,产生了sandbox的效果,所以很多提权操作是不允许的

eval "return io.popen('ifconfig')" 

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABQsAAAAoCAIAAADWoTurAAARDUlEQVR4nO2d2aHrIAxEb09ux8W4F2pxKenjfSS2Ac0I4SVO8uZ83UtYJBYhGRL//b0YpvkxT8Pf39/f35ief47pkcbt4/UfIYQQQgghhBDipxnT48UrFM4iZMXIQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEKIYZpfv2m+vP7rVxim+Ut+jj0qKc63jOCZ44fqPNKf3zMWQgghhBDi/2SNi2oXmPraY2r54FusVb82qqozy9jy7LFIWQWwWt8Xh3Li4rghjHl9Fiq+ZSoz9zR0CctbsQP50ngg4Bmm+dci8cOgvo/3U/GWtvMkOlInEh6kxedSdGkLIYQQQghxCOiGw8QxzSm5PvswzYv3Okxz5fKXdXZHSWWBMW2O8vZJFma40R6RExUf01ZNw48vVB6nWPFVeKzRW1GEfBswHA330xWns0frDNqV6FyKLm0hhBBCCCEOEo2Qx/RIY09sUzv9Z0bIVelXHFq0GG5gLdUu7tbZPnPDvfpMQhp1Bin2rnQZSywCbmfYNlrZHyEP0zxPUyprNiLV5+dprHQvZDB1FgkNWde261kYKZ035F+xYDmt7o7wuOfr+YI0Yncx3NsQUHhUFo4l7M+UklEfqGQUDUbI+5a2EEIIIYQQ/cRCwdepa4dvanxhEyFXcVKPnCaefLnZNjEuZ7t4fsz70qBy2yd7y5oVX6p4pZDW498vzfp7qzZXwipUxyWHDueGaXbivqIpEPnRCBkEqNud9Pb42jB+65nmzX6TExXHOVEpLnzPoxCU16QVkkyboI7wdR38+86sPyOTZ+fJ9L6lLYQQQgghxA4iEfL6b8/BLIjHSFmQuSVndSf58Zin4en4r05/KN7L6qHF8eFZHSGP6VGKlAdIOGguwgWkUdWY8yyhjDyKe+ebeqZw1UWHI2RzuojP/boiZFpnSFojRF68cWPe5NyXuOrHhe85FA1EyDAMjQhfP4xoRcjdw7E3uEVrs7sSIYQQQgghIgQi5M2rjbnyeXzYaMi0EJYzv8Q67TtDLuWMnSFTFfqL1zGF1ch+5kXIJVVgnMlT5D0zQjZ3BrBIXREyv4ewL0IOFoc5uxKt7rz1k8+Qm0vaF96TaW9/+rU20RmyEEIIIYR4G+0I2f72cut+Kvz85AgZfNT1ZUUrZ6C4J2f+o1wkZ57oxgr5oX3olrV7QJ/G8iEHO/c7PUImtd0ZIb/tDDkYo3bogjSCaV1nyAcj5M4z5L1TTN9DFkIIIYQQ7yJyy5qmVzeNeXhcly3CSff7vaTp5duV4KJ0/WdYTlC8kNOcOZdyVse08zQ4xW0AYjXqOnArFB5Tcf07pVK0rbsCQVEQMGWYSKadLWMp0tkRcvYvPMCHk/Dw95AX3T3h46eigQi563vIRyLkss7YcOyMbenSFkIIIYQQ4jTKw+EsbLIXY180IuT6tDk7XzKpeZq9UFz7+7bS/E5y6de362RyouLFhdm8UhDJZ/XCK82FBMbLxxrFyZqy3ZelrFKa3x9ePzp+ETYgEhrMUqQjETIZ47WlqqyNkM/7Lev2gW0o7KOzFkWzaCEQ4WMRcqM/7VwCHDr8JUtbCCGEEEIIIcS1xGO5s678HjrA/wBiX/v/Zg2FEEIIIYQQ4v/k/RHydzJMab0e/x93gxBCCCGEEEL8MIqQo0R/S04IIYQQQgghhBBCCCGEEEIIIYQQQgghhBDiy7jtB3T0yz2n84Fdeo1Iu2qFPxZ+9BfE+7n8XvL/fvE7xgf30v0317/la+VtOT/MJKJZ934ThDizoz5Do9/jwybzCfyeRp18i6X9Ag7OpcunYodVDDsnb7e0gV569x538cDduUIj86B6y8wzf5Vo3x/lvxMG1ilupStgOTRpYeFwjYcDq/irj23LdtaixD4R/Tec4beelS+Mai+4J9uyg7X6iVkd1TvJS4GQnPWbqh6PNOJegjlxQzgRv00Ma8S6bvcMoe8yc/OixsrlYAYuPBVxcda6SWTDgeSkun/UoxBHmAt24itU76jzbI3c6R17I/v/QXCMesyFW35/FR1NHWmBvYvyztXxJLBGPsqA/QA392fEKvaK+FHPWS7c464wAw32e2NnEJC4Hc8M0/yYpwEnxusUt9IzeY9N2nsj5P0PvMK7fGdXLnmXP4dpzt/m/foYVwqKc+m3z8dpjanyptLIEtfm5pTmrMU85xqn+covGdq9tOaADcHEuqTRYvubdt3hR6LBB4/ewFWRJxi4qMOJiuPWW3MJ1W8yHl0PBvS06ACKkK8RoLQM/ztd4753khirdaUjqQj5mFxiQxHytfxUhAwkZndR52lK5QcokZ6h2OKk/baEJvEZMcHEeJ1XqtluKB+7VbwiV+ax2sRMouKcBuVcs6bU6H14csbPf2rdGyLl+ha0dlp30q6Ft1qrzLsjZCZn9FE8PWTzmipGuCNCrju5FGARvVgkJARZT1Fhr4HiSHi4GmFxLtKYHmncUiqJxhQKfOHigiXKnHVDuHUkdoeabIYAm0ynN+gCW5x0MrAMcODiDucZ474WMv1hLRgTYt++mof32RMR05/E0oIxcmZddC8mctoRhsYqaKjLWsmRfqehhnucO5OZsmBu5JYhDhGpufG1XCPclF/nPZvpbq/Tc6Ju0wjMJVjcWx1ZBcM0z/P8eDwtzQOu97acaNoEfbCjLgdbXGyMvESwGyH/syFT3NHFrQ/TXLgv22P1WvIOq3iF80xz2oVjR5NsE30+bY25GFYthVYsAzv5bXvcVjWax4VRoKuj39QN5rii2iaKFQl1MwKbExJWHAtQ89Yz5KvUbDfEDEd+zTO78FknGsF4zkJ4T9qisvXFt4XKy5mQozsVyXGffNxJm4tE8p98hswmQ1j6aPYifDJbZW3vrUigl0yYx2+xkobc4sWkzeytnYrZ3zDx+Xcaq3AOtA57iXYnH7gyp23I1b38EGnkFDczhNhklh3UXRfnXVdbBj5w0aloi/f3J5sV1oJBM0J6rbUOq2LLv7g/qU0uE51ZZ2ahP+5Ezs1Q/+HeiBlqblQ7vIxYhEwlIGOELDCY1NEhxtuuv/E1XSPU0O2babQ/46ujsZHe4h6geqlZ4A78MM2PND1rMR5mj5xo2oR9MFxnp8tRlSFj1ErMbZ2ZydwEecr4jq674ipDbPL0WkVY/IDz7OTkYlfeljPEIZ/WkG+q1tcD+ge2CfDBFXucB9mnDzwZL+r255grvUmsZjeZrQXwjKHKkLNNuhX4fMjtGVjnpWrWoDr9rdpPhNV2F7cyNr2Y5geuSK09jMnlKA2o1Dw3QuYa0fJddgALlh1o2UQoEmz3Wflq0YA9g7Iu6Y3iWcqYqlAqn+x2wdrEtduz/s/FgwbdyI/jrOZ2ARvyWod+Um2sWNdRg49rtt1e5IHFYevQMvCByzWjUxEWh637c8kZuECETMa3tQ6XUsMz9J/n+ZFG2J9No8rMr+PlNMe9yIk/RKX6DXW7TkJnhIx6oB3RIcvgFad1FWPU6LaWa4Qaun0zjfWnk9OQOVLg4cL1GvmiuQYZJNohXi7ub48QW6s45FHHfbBmnRGXo2oo5uS6wsOZ3O8/xR1dsKlZJ9/OpbhVhMUPOs8kp2PnobcGhzji01q2qlClRSWxBQuLX7HHeURtyB5qdV8zz0aPIQvDt0Cqe3t7aW6lq4cGE+N1UjlPULPdEDMcwcStFjLjQsWRmNUTB28k4QcBkfyKGzW6Bg8+MDk9Qo73J5Ce5/Kf9jC7mcb2uDNlzOMeqo1tKCsOhMc56yBz8UZgIrJE+fycmvd5+WL1Hm3yhnjrpbpII6fnqxlCbLIzQ0gXZcVh65Fp48w6mNhsyE/M/gsOHJvmO3bKpaqljWctzf7MRGoshLbnBPdiIiuaCqg3+g11rDwgFiG3bZ0nALEMQdhwwI0PD0e42Y/cTHsz8zqQWWs3crJGbC6FHDs7xPO8moA6Qg7K2WMuHKV2uxztvdjvIDjnobUhJshTpunocgOIHHxj5jusoil+0HnusvPhhvp8WsBiLbPtldQZW7Dv3OMoURuyC2e0aiECqyoXtfa2cb1tFQLxzOs/mBivk8p5gprthroMB50BsUXe8/zyzynua8REOv6Q2H0QhRtqWpMjEXLXI6uItx4ZIz8s8Z9Kkloy1dbQlLCFuMEH5OX3dHsjpdH8pnHQ8W9EnmTg3DGK2Ig6RrUaOYbDyol9FzpDvNZLIYos8YHzKjNqRnXv6ZCg7lmzOzbKOkJ+Stgcft/SOrMuuhe7tOOKfkMdK98U5qz9qBAgYBmidfn7Qnfsx/mozfScCBltPaFGTtWIz6VohFxlqmxTHiEH5ey33lCtnS5H0wTBnL7wOTtcqX2OLhB2MhJzmxV62nKq8xz3P5veGkvcEyFv/tT2fA/XuWvBvmeP6xJpT8hdUNdRqDCm7EFDIHTMpIs9AQz0UGQRPh8owcR4nVSe42pGGsp9UvdhzMEIuRTeX+TrdzfYOiq/aBRcUbDrQpHjgjdp7c8k12rGdwiEycgmQ7S8n2cTvog1xvUWK0gknQwHLkssLFytCGwIFic9n43ZUn/ZzqtSmFj2DZh+43aRBMr5Zzu+ZyqChkiiFZJphHoeNw9ssjO9UUhuTTobd2sZwMDFpyIsTnRnHeKvuECETNKaD6wX0YftSfcrvgfD4bpThUknsy407hBiqFGVpDdQXmLneww1r7LsEMdQg6aizkRkiIlIzY2v5RoB4e7fTOP9Gem6If/xari03+4e8LkU3PPrIZ6cCDm8d4BpE/bBcJ1hl4Pvxa4ngBNXWwdmMjdBhrCjy1bc2gDa0fO51GMVQfFDzrOTk4tdtgMTe3xayJgeKZV7MqyzO0K+do/zoMMbfm7gYmqp/IE1MRI6ZqXrjkGiRjaXkfwUoen4eZ5BIqwe1nmdmgC2Kz0ej+y37zoiZKQSi6WXlnp+y9rEFnUqjPmxSOQHhNf87WXiTNq18FadUXP5qF6rsdaNnHgyEGK2DAqfd6hVc0ukncwGrkwkqwO23tPzWQVQ+nyu2sSsvTJ4qvMROdGUwb2E7CpqCCeWvQf6DklP/B/QfO5bg06GrVOTTtOaAxediqR4dCq2hiOgOzfqPeETbn5thnt49Rh5BtCaIGKA2wKZKr09jm2HZH52Guo8J9jjHENtx4gNMVQsNMRYpObG15peXkO3babx/ox1HVnwd7oHfNOHxeHqyAQaeITcISca+bAPhusMuxykQ+LmFwjf2E4Cj1ZqkZinCmo1T70fyd4xW60yEanqz0ucZydnbeftaJIJ1uvTIsZU5uIzJLRNvG2Po7oYkfoc8jbxxw8nc1vD4sV4wiWEPuLPEJr1aO4IIRocshTBSEGIGzhrM/0cvkWjb5FTXEfceX6/my2E2M16/eScSwidbWtrEUJ8Ddtzark54pP4vc30WzT6FjnF2cSd5zvdbCHEAZZbCO9fuNpaCupbIvLEhRCEDzQXHyjSvbyxQ35vM/0Wjb5FTnE+cef5PjdbCCGEEEIIIYQQQgghhBBCCCGEEEKI3YQvR8V/uvhttFvX912EEEIIIYQ4AvxNbPeHstsvb/N/CB6GG82Yg75ZCRRmL6gIyem/ASUSGYFfdbHF7TeVzI/Td0c6VZ3be8k2PcoAakx5M32/tvfMvf9HYt/4LZ6yqd6GYcx5byDqtA5egWZ/rz84cNF1JIQQQgghxK/B3haJQoM5JTfEGLaXyA/mZcTHgpWqQP5WtO0T9rLxoJyo+JjKl7M5AUOh8uud683iq/BYoyhY3fo9bmW4PG8JipAh/2uEHF1HQgghhBBCfD//AHWdNV6HHpDAAAAAAElFTkSuQmCC" alt="" />

2. EVALSHA 则要求输入某个脚本的 SHA1 校验和, 这个校验和所对应的脚本必须至少被 EVAL 执行过一次

Relevant Link:

http://www.redis.cn/commands/eval.html
http://origin.redisbook.com/feature/scripting.html

Copyright (c) 2014 LittleHann All rights reserved

Redis Installation、Configuration、Program Based On Redis Learning的更多相关文章

  1. Nginx Installation、Configuration、Rreverse Proxy、Load Balancing Learning

    目录 . Nginx简介 . Nginx安装部署 . Nginx安全配置 . Nginx反向代理实践 . Nginx负载均衡实践 1. Nginx简介 0x1: Nginx的基本特性 Nginx(&q ...

  2. Spring 学习——Spring常用注解——@Component、@Scope、@Repository、@Service、@Controller、@Required、@Autowired、@Qualifier、@Configuration、@ImportResource、@Value

    Bean管理注解实现 Classpath扫描与组件管理 类的自动检测与注册Bean 类的注解@Component.@Service等作用是将这个实例自动装配到Bean容器中管理 而类似于@Autowi ...

  3. SPRING IN ACTION 第4版笔记-第二章-001-用@Autowired\@ComponentScan、@Configuration、@Component实现自动装载bean

    1. package soundsystem; import org.springframework.context.annotation.ComponentScan; import org.spri ...

  4. 14 - springboot的@Configuration、@Bean、@Import()、@ImportResource()、@Conditional说明

    1.@Configuration.@Bean.@Import().@ImportResource().@Conditional 分析源码的时候总会见到标题中的这几个注解,因此:弄一篇博客来说明一下吧, ...

  5. Docker部署Django项目+Nginx+Fluend日志收集 和redis、memcached、RabbitMQ、Celery

    前言 一.docker 1.docker是什么? Docker的英文本意是“搬运工”,Docker搬运的是集装箱(Container)可以成为容器,我可以把写的Django的WEB应用以及Python ...

  6. Redis之高可用、集群、云平台搭建(非原创)

    文章大纲 一.基础知识学习二.Redis常见的几种架构及优缺点总结三.Redis之Redis Sentinel(哨兵)实战四.Redis之Redis Cluster(分布式集群)实战五.Java之Je ...

  7. ASP.NET Core 使用 Redis 实现分布式缓存:Docker、IDistributedCache、StackExchangeRedis

    ASP.NET Core 使用 Redis 实现分布式缓存:Docker.IDistributedCache.StackExchangeRedis 前提:一台 Linux 服务器.已安装 Docker ...

  8. 8、Docker常用安装:tomcat、mysql、redis

    1.总体步骤 搜索镜像 拉取镜像 查看镜像 启动镜像 停止容器 移除容器 2.安装tomcat 1.docker hub上面查找tomcat镜像 docker search tomcat 2.从doc ...

  9. Redis之高可用、集群、云平台搭建

    原文:Redis之高可用.集群.云平台搭建 文章大纲 一.基础知识学习二.Redis常见的几种架构及优缺点总结三.Redis之Redis Sentinel(哨兵)实战四.Redis之Redis Clu ...

随机推荐

  1. 16进制色值转换成RGB

    #51147f  转换成RGB ,5*16+1 ,1*16+4,7*16+15 #A9A9A9 转换成RGB ,A*16+9 ,A*16+9,A*16+9

  2. localStorage实现购物车数量单价和总价实时同步(二)

    利用localStorage实时显示购物车小计和总价页面显示: 和昨天的原理相同,本地存储同时实时循环计算总价之和,注意循环时候的先清空再计算 Success is getting what you ...

  3. 如何将NTFS格式的移动硬盘挂接到Mac OS上进行读写(Read/Write)操作

    现在硬盘便宜,很多同学都有移动硬盘,如果你同时使用Windows与Mac OS的话,移动硬盘最好不要使用NTFS文件系统,否则在Mac OS上,你只能读你的移动硬盘,不能写. 但是实际上的情况是,移动 ...

  4. 联想Y50p预装win8系统改为win7

    &1 修改OS Optimized Defaults 开机,按[F2]进入BIOS设置,按右方向键选择到EXIT上面,按下方向键选择OS Optimized Defaults,回车,将Win8 ...

  5. JS案例之5——移动端触屏滑动

    移动端触屏滑动的效果其实就是图片轮播,在PC的页面上很好实现,绑定click和mouseover等事件来完成.但是在移动设备上,要实现这种轮播的效果,就需要用到核心的touch事件.处理touch事件 ...

  6. Word 文档插入时间日期禁止自动更新

    前些天写了点总结并插入时间和日期,记得勾掉了那个自动更新的,但是刚才打开时发现当时的日期和时间变成现在的了,我就纳闷了,然后我去看那插入日期和时间的那个框,里面确实没有勾选自动更新,于是百度, 百度都 ...

  7. Linux常用指令---grep(搜索过滤)

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达 ...

  8. Java Platform Standard Edition 8 Documentation

    下面这个图挺有用的,收藏一下. Oracle has two products that implement Java Platform Standard Edition (Java SE) 8: J ...

  9. Linux第二次报告20135221

    学习计时:共xxx小时 读书: 代码: 作业: 博客: 一.学习目标 1. 熟悉Linux系统下的开发环境   2. 熟悉vi的基本操作   3. 熟悉gcc编译器的基本原理   4. 熟练使用gcc ...

  10. Opencv step by step - 基本数据类型

    CvArr,CvMat,IplImage这三者是继承的关系. 打开opencv 3.0的源码: cvArr /* CvArr* is used to pass arbitrary  * array-l ...