Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。
默认情况下,Redis有16个数据库,从0号数据库到15号数据库。
Redis官网
参考:Redis百度百科
##安装
wget http://download.redis.io/releases/redis-4.0.2.tar.gz
tar zxf redis-4.0.2.tar.gz
cd redis-4.0.2/
make
make test
sudo make install #默认安装在/usr/local/bin目录下
#也可以自定义安装目录
sudo make PREFIX=/usr/local/redis install
注:redis是C语言开发,安装redis需要先将官网下载的源码进行编译,编译依赖gcc环境。如果没有gcc环境,需要安装gcc:
redis需要依赖tcl,make test会报错:You need tcl 8.5 or newer in order to run the Redis test
解决方法:安装tcl
sudo yum install gcc-c++
sudo yum install tcl
##配置及启动与关闭
文件redis.conf为配置文件
bind 127.0.0.1 #绑定ip
port 6379 #默认端口
daemonize no|yes #是否以守护进程运行,需修改为yes以守护进程运行
注:daemonize 为no时无法配置集群模式
启动redis-server需指定配置文件
./redis-server ../redis.conf #常将配置文件放在/etc/redis目录下,对应指定配置文件路径即可
启动redis-cli
./redis-cli #默认启动本机127.0.0.1:6379
#或
./redis-cli -h 127.0.0.1 -p 6379 #指定ip地址与端口号
设置redis-server开机启动
vim /etc/rc.local
//添加
/redis安装路径/redis-server /配置文件路径/redis-conf
sudo chmod +x /etc/rc.d/rc.local #需添加执行权限,否则boot时不执行
关闭redis-server
./redis-cli shutdown #正常关闭,否则容易造成数据丢失
##5种数据类型及对应常用命令
###1.string
- string是redis最基础的类型
- 最大存储512MB数据
- string类型是二进制安全的,可以为任何数据
注:二进制安全
redis编码解码只会发生在客户端,服务器与硬盘存储的都是二进制数据,不用频繁编解码,执行速度快,不会出现乱码。
而关系型数据库如mysql,在数据插入和查询时服务器与客户端及硬盘间存在大量编解码,执行速度慢,容易出现乱码。
设置单个键值
SET key value
设置键值及过期时间,以秒为单位
SETEX key seconds value
设置多个键值
MSET key value [key value ...]
根据键获取值,如果不存在此键则返回nil
GET key
根据多个键获取多个值
MGET key [key ...]
运算
将key对应的value加1
INCR key
将key对应的value加整数
INCRBY key increment
将key对应的value减1
DECR key
将key对应的value减整数
DECRBY key decrment
追加值
APPEDN key value
获取值长度
STRLEN key
查找键,参数支持正则
KEYS pattern
判断是否存在,如果存在返回1,不存在返回0
EXISTS key [key ...]
查看键对应的value的类型
type key
删除键及对应的值
del key
设置过期时间,以秒为单位,创建时没有设置过期时间则一直存在,知道使用del移除
expire key seconds
查看有效时间,以秒为单位
TTL key
###2.hash
hash用于存储对象,对象的格式为键值对
设置单个属性
hset key field value
设置多个属性
hmset key field value [field value]
获取一个属性的值
hget key field
获取多个属性的值
hmget key field [field ...]
获取所有属性和值
hgetall key
获取所有的属性
hkeys key
返回包含属性的个数
hlen key
获取所有值
hvals key
判断属性是否存在
hexists key field
删除属性及值
hdel key field [field]
返回值的字符串长度
hstrlen key field
###3.list
- 列表的元素类型为string
- 按照插入顺序排序
- 在列表的头部或者尾部添加元素
在头部插入数据
LPUSH key value [value ...]
在尾部插入数据
RPUSH key value [value ...]
在一个元素的前|后插入新元素
LINSERT key BEFORE|AFTER pivot value
设置指定索引的元素值
索引是基于0的下标
索引可以是负数,表示偏移量是从list尾部开始计数,如-1表示列表的最后一个元素
LSET key index value
移除并且返回 key 对应的 list 的第一个元素
LPOP key
移除并返回存于 key 的 list 的最后一个元素
RPOP key
返回存储在 key 的列表里指定范围内的元素
start 和 end 偏移量都是基于0的下标
偏移量也可以是负数,表示偏移量是从list尾部开始计数,如-1表示列表的最后一个元素
LRANGE key start stop
###4. set
- 无序集合
- 元素为string类型
- 元素具有唯一性,不重复
添加元素
SADD key member [member ...]
返回key集合所有的元素
SMEMBERS key
返回集合元素个数
SCARD key
5 zset(sorted set)有序集合
- 元素为string类型
- 元素具有唯一性,不重复
- 每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序
- 元素的score可以相同
添加元素
zadd key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]
返回指定范围内的元素
ZRANGE key start stop
返回元素个数
ZCARD key
返回有序集key中,score值在min和max之间的成员
ZCOUNT key min max
返回有序集key中,成员member的score值
ZSCORE key member
更多命令介绍:http://redis.cn/commands.html
##主从配置
redis支持集群。 一个master可以拥有多个slave,一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构
比如,将ip为192.168.1.10的机器作为主服务器,将ip为192.168.1.11的机器作为从服务器
主服务器配置:
bind 192.168.1.10 #主服务器ip
从服务器配置:
bind 192.168.1.11 #从服务器ip
slaveof 192.168.1.10 6379 #端口必须写
或者在从服务器上运行命令:slaveof 192.168.1.10 6379
##安装hiredis
使用C/C++操作Redis,需要安装C/C++ Redis Client Library
选择使用hiredis
git clone https://github.com/redis/hiredis
cd hiredis
make
sudo make install(复制生成的库到/usr/local/lib目录下)
sudo ldconfig /usr/local/lib
##C/C++操作Redis
#include <iostream>
#include <string>
#include <hiredis/hiredis.h>
int main(int argc, char **argv)
{
struct timeval timeout = {2, 0}; //2s的超时时间
//redisContext是Redis操作对象
redisContext *pRedisContext = (redisContext*)redisConnectWithTimeout("127.0.0.1", 6379, timeout);
if ( (NULL == pRedisContext) || (pRedisContext->err) )
{
if (pRedisContext)
{
std::cout << "connect error:" << pRedisContext->errstr << std::endl;
}
else
{
std::cout << "connect error: can't allocate redis context." << std::endl;
}
return -1;
}
//redisReply是Redis命令回复对象 redis返回的信息保存在redisReply对象中
redisReply *pRedisReply = (redisReply*)redisCommand(pRedisContext, "set words_in_redis Hello_World"); //执行set命令
std::cout << pRedisReply->str << std::endl;
//当多条Redis命令使用同一个redisReply对象时
//每一次执行完Redis命令后需要清空redisReply 以免对下一次的Redis操作造成影响
freeReplyObject(pRedisReply);
pRedisReply = (redisReply*)redisCommand(pRedisContext, "get words_in_redis");
std::cout << pRedisReply->str << std::endl;
return 0;
}
编译:g++ redis.c -l hiredis
执行:./a.out
程序执行了set words_in_redis Hello_World并从数据库返回words_in_redis的值
集群配置问题:
192.168.2.11:6379> set msg “hello world”
(error) READONLY You can’t write against a read only slave.
从服务器是只读的
若不修改bind 127.0.0.1 其他客户端无法连接
集群功能默认关闭,修改redis.conf文件
cluster-enabled yes
参考:
http://hahaya.github.io/operator-redis-under-linux/
Redis 中的事务
Redis支持简单的事务
Redis与 mysql事务的对比
Mysql Redis
开启 start transaction muitl
语句 普通sql 普通命令
失败 rollback回滚 discard 取消
成功 commit exec
注: rollback与discard 的区别
如果已经成功执行了2条语句, 第3条语句出错.
Rollback后,前2条的语句影响消失.
Discard只是结束本次事务,前2条语句造成的影响仍然还在
注:
在mutil后面的语句中, 语句出错可能有2种情况
1: 语法就有问题,
这种,exec时,报错, 所有语句得不到执行
2: 语法本身没错,但适用对象有问题. 比如 zadd 操作list对象
Exec之后,会执行正确的语句,并跳过有不适当的语句.
(如果zadd操作list这种事怎么避免? 这一点,由程序员负责)
思考:
我正在买票
Ticket -1 , money -100
而票只有1张, 如果在我multi之后,和exec之前, 票被别人买了—即ticket变成0了.
我该如何观察这种情景,并不再提交
悲观的想法:
世界充满危险,肯定有人和我抢, 给 ticket上锁, 只有我能操作. [悲观锁]
乐观的想法:
没有那么人和我抢,因此,我只需要注意,
–有没有人更改ticket的值就可以了 [乐观锁]
Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.
具体的命令---- watch命令
例:
redis 127.0.0.1:6379> watch ticket
OK
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> decr ticket
QUEUED
redis 127.0.0.1:6379> decrby money 100
QUEUED
redis 127.0.0.1:6379> exec
(nil) // 返回nil,说明监视的ticket已经改变了,事务就取消了.
redis 127.0.0.1:6379> get ticket
“0”
redis 127.0.0.1:6379> get money
“200”
watch key1 key2 … keyN
作用:监听key1 key2…keyN有没有变化,如果有变, 则事务取消
unwatch
作用: 取消所有watch监听
redis远程访问
本地访问云服务器上的redis
1 修改配置文件
bind 0.0.0.0
protected-mode no
requirepass yourpasswd
2 开放云服务器 redis(默认6379)端口
3 重启redis
/etc/init.d/redis restart
4 连接远程redis
redis-cli -h your_ip [-p 6379] [-a yourpasswd](也可登录后用 auth yourpasswd 授权)
参考: