redis学习第一章
安装
linux下安装redis。redis命名规则,redis约定次版本号为偶数的是稳定版本(2.8,3.0),次版本号为奇数的为非稳定版本(2.7,2.9)。
wget http://download.redis.io/redis-stable.tar.gz//下载稳定版本
tar -zxvf redis-stable.tar.gz//解压
cd redis-stable
make && make install //直接编译安装
make test //测试
编译安装完成之后,执行测试,可能遇到的问题
- You need tcl 8.5 or newer in order to run the Redis test
//安装tcl
wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
tar xzvf tcl8.6.1-src.tar.gz
cd /tcl8.6.1/unix/
./configure
make && make intsall
make test
启动和停止
如果在编译后执行了make install 命令,这些程序会被复制到/user/local/bin目录内,所以在命令行中直接输入程序名称即可执行,redis可执行文件说明:
文件名 | 说明 |
---|---|
redis-server | redis服务器 |
redis-cli | redis命令行客户端 |
redis-benchmark | redis性能测试工具 |
redis-check-aof | AOF文件修复工具 |
redis-check-dump | RDB文件检查工具 |
redis-sentinel | Sentinel服务器(仅在2.8版以后) |
- 启动redis
启动redis有直接启动和初始化脚本启动,两种方式,分别适用于开发环境和生产环境。
redis的默认端口为6379,不过可以通过redis-server -p 6380 这种形式来自定义端口号。ps:值得一提的是6379是手机键盘上,MERZ对应的数字,Merz(Alessia Merz)是一名意大利歌女的名字,并且长期以来都被Antirez极其朋友视作愚蠢的代名词(有点侮辱性)
1).直接启动
直接运行redis-server就可以启动redis
2).通过初始化脚本启动redis
在生产环境中推荐使用此方法运行redis,在redis源代码目录的utils文件夹中有一个名为redis_init_script的初始化脚本文件。我们需要配置redis的运行方式和持久化文件、日志文件的存储位置等,具体步骤如下:
1). 配置初始化脚本,配置初始化脚本,首先将/redis-stable/utils/redis_init_script文件复制到/etc/init.d目录中,文件名为redis_端口号,该端口号表示要让redis监听的端口号,客户端通过该端口连接redis。然后修改脚本中的REDISPORT变量为该端口号。
2).建立需要的文件夹。
/etc/redis 存放redis的配置文件
/var/redis/端口号 存放redis的持久化文件
3).修改配置文件。首先将配置文件模板(redis-stable/redis.conf)复制到/etc/redis目录中,以端口号命名,然后对其参数进行编辑
deamonize参数修改为yes 使redis以守护进程模式运行
pidfile参数修改为/var/run/redis_端口号.pid 设置redis的pid文件位置
port参数修改为端口号 设置redis监听的端口号
dir参数修改为/var/redis/端口号 设置持久化文件存放位置
ps:添加开机自启动,在/etc/init.d/下 systemctl enable redis_端口号
- 停止redis
考虑到redis有可能正在将内存中的数据同步到硬盘中,强行终止redis进程可能会导致数据丢失,正确停止redis的方式应该是向redis发送SHUTDOWN命令,方法为:
redis-cli SHUTDOWN
ps: redis-cli -h 127.0.0.1 -p 6379 (-h -p 自定义地址和自定义端口)
当redis收到SHUTDOWN命令后会先断开所有客户端连接,然后根据配置执行持久化,最后完成退出,redis可以妥善处理SIGTERM信号,所以使用kill Redis进程的PID也可以正常结束redis,效果与发送SHUTDOWN命令一样
什么是redis
redis(REmote DIctionary Server 远程字典服务) 由意大利的一个创业公司开发,开发者Salavtore Sanfilippo
redis的特性
-
存储结构->字典(或称映射、关联数组),键值对的形式存储
键值的数据类型->
字符串类型 set/get
散列类型 hset/hget
队列类型 lpush/lpop
集合类型 sadd/smembers
有序集合类型 zadd/zrange -
内存存储于持久化
redis数据库中的所有数据都存储在内存中。由于内存的读写速度远快于硬盘,因此redis在性能上对比其他基于硬盘存储的数据库有非常明显的优势,在一台普通的笔记本电脑上,redis可以再一秒内读写超过10w个键值对
同时redis还提供了将内存中的数据异步写入到硬盘,同时不影响继续提供服务 -
功能丰富
redis是作为数据库开发的,提供了丰富的功能,越来越多的人将其用作缓存、队列系统等。redis可谓是名副其实的多面手redis可以为每个键设置生存时间(Time To Live TTL),生存时间到期后键会自动被删除,这一功能配合出色的性能让redis可以作为缓存系统来使用。
作为缓存系统,redis还可以限定数据占用的最大内存空间,在数据达到空间限制后可以按照一定的规则自动淘汰掉不需要的键
redis的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易地实现一个高性能的优先级队列。同时在更高层面上,redis还支持"发布/订阅"的消息模式,可以基于此构建聊天室等系统
-
简单稳定
初步使用redis
- 基础命令
1).KEYS pattern
pattern 支持glob风格通配符
符号 | 含义 |
---|---|
? | 匹配一个字符 |
* | 匹配任意个字符 |
[] | 匹配括号间的任一字符,可以使用“-”符号表示一个范围,如a[b-d]可以匹配“ab”、“ac”、“ad” |
\ | 转义字符 |
注意:keys命令会遍历redis中所有的键,当键的数量较多时会影响新能,不建议生产环境中使用;redis命令不区分大小写
2). 判断一个键是否存在EXISTS key
如果键存在则返回整数类型1,否则返回0,例如:
redis > EXISTS bar
(integer) 1
redis > EXISTS noexists
(integer) 0
3).删除键DEL key [key ...]
可以删除一个或多个键,返回值是删除的键的个数。例如:
redis > DEL bar
(integer) 1
redis > DEL bar
(integer) 0
第二次执行DEL命令时因为bar键已经被删除了,实际上并没有删除任何键,所以返回0
技巧:DEL命令的参数不支持通配符,但我们可以结合linux的管道和xargs命令自己实现删除所有符合规则的键,比如要删除所有以"user:"开头的键,就可以执行redis-cli KEYS “user:*” | xargs redis-cli DEL。另外由于DEL命令支持多个键作为参数,所以还可以执行 redis-cli DEL "redis-cli KEYS “*”"来达到效果,而且性能更好,该方法是讲明了作为redis-cli参数来进行的
- 字符串类型
字符串是redis种的基本数据类型,一个字符串类型键,允许存储的数据的最大容量是512m。
1).赋值与取值
set key value
get key
SET和GET是redis中最简单的两个命令,实现基本的读写功能。如设置键为key 值为hello的键值对
redis > set key hello
OK
获取键值
redis > get key
“hello” //当键不存在时返回空结果
- 递增数字
INCR key
字符串类型可以存储任何形式的字符串,当存储的字符串为整数时,redis提供了一个实用的命令INCR,其作用是让当前的键值递增,并返回递增后的值,用法为:
redis > incr num
(integer) 1//当操作的键不存在时,默认的键值为0
redis > incr num
(integer) 2
当键值不是整数时redis会提供错误(即使是浮点类型的)
Q:为什么不自己写get和set来实现递增incr函数?
A:因为如果连接redis的同时有多个客户端,同一时间多个客户端发起该请求,那么可能会出现竞态条件(竞态条件 race condition 指一个系统或进程的输出,依赖于不受控制的事件的出现顺序或出现时机),比如两个客户端A和B都要执行自定义的incr函数,当他们执行到get时都获得了该num为2,递增后使num变为了3,可是执行了两次,我们的期望应该是4,这就出现问题了。所以使用redis的INCR命令在内的所有命令都是原子操作,无论多少客户端连接都不会出现上述情况。(当然还可以通过事物和脚本实现自定义原子操作)
Redis命令行客户端
-
通过redis-cli向redis发送命令的方式有两种:
第一种:将redis-cli作为参数执行,比如reids-cli SHUTDOWN,redis执行时会自动按照默认配置(服务器地址为127.0.0.1,端口号为6379)连接redis,通过-h和-p参数可以自定义地址和端口
redis-cli -h 127.0.0.1 -p 6379
redis-cli PING
第二种:不附带参数运行redis-cli,这样会进入交互模式,可以自由输入命令,例如
redis-cli
redis 127.0.0.1:6379>PING
PONG
这种方式要在输入多条命令比较方便 -
命令返回值
1).状态回复(status reply)
状态回复是redis里最简单的一种回复,如向redis发送set命令设置某个键的值时,redis会回复状态ok表示设置成功。
2).错误回复(error reply)
当出现命令不存在或命令格式有错误等情况时Redis会返回错误回复(error reply)。错误回复以(error)开头,并在后面跟上错误信息。如执行一个不存在的命令:
redis > ERRORCOMMEND
(error) ERR unknow command ‘ERRORCOMMEND’
注意:在2.6版本时,错误信息均是以“ERR”开通,而在2.8以后,部分错误信息会以具体的错误类型开头,如:
redis > LPUSH key 1
(integer) 1
redis > GET key
(error)WRONGTYPE Operation against a key holding the wrong kind of value
3).整数回复(integer reply)
Redis 虽然没有整数类型,但是却提供了一些用于整数操作的命令,如递增键值的INCR命令会以整数形式返回递增后的键值。除此之外,一些其他命令也会返回整数。如可以获取当前数据库中键的数量DBSIZE命令等。整数回复以(integer)开头,并在后面跟上整数数据
4).字符串回复(bulk reply)
字符串回复是最常见的一种回复类型,当请求一个字符串类型键的键值或一个其他类型键中的某个元素时就会得到一个字符串回复。字符串回复以双引号包裹:
redis>GET foo
“1”
5).多行字符串回复(multi-bulk reply)
该回复同样很常见,如当请求一个非字符串类型键的元素列表时就会收到多行字符串回复。多行字符串回复中的每行字符串都以一个序号开头,如:
redis > KEYS *
1). “bar”
2). “foo” -
配置
由于配置选项较多,通过启动参数这些选项并不方便,所以Redis支持通过配置文件来设置这些选项。启用配置文件的方法是在启动时将配置文件的路径作为启动参数传递给redis-server,如:
redis-server /path/to/redis.conf
通过启动参数传递同名的配置选项会覆盖配置文件中相应的参数,如:
redis-server /path/to/redis.conf --loglevel warning
redis提供了一个配置文件的模板,位于源代码目录的根目录中。
除此之外还可以在redis运行时通过CONFIG SET命令在不重新启动redis的情况下动态修改部分redis配置。如:
redis>CONFIG SET loglevel warning
OK
同时使用CONFIG GET命令可以获得当前redis配置的情况,如:
redis > CONFIG GET loglevel
1). “loglevel”//选项名
2). “warning”//值 -
多数据库
每个数据库对外都是一个从0开始的递增数字命名的,redis默认支持16个数据库,可以通过配置参数database来修改这一数字。客户端和redis建立连接后会自动选择0号数据库,不过可以随时使用select命令更换数据库。
redis不支持自定义数据库名称,开发者必需自己记录哪些数据库存储了哪些数据。
redis不支持为每个数据库设置单独的访问密码,因此一个客户端要么可以访问全部数据库,要么连一个数据库都不能访问。
多个数据库之间并不是完全隔离的,比如FLASHALL命令可以清空一个redis实例中所有数据库中的数据。不同的应用不建议存储在一个redis实例中。由于redis非常轻量级,一个空redis实例占用内存只有1mb左右,所以不用担心多个redis实例会额外占用很多内存。