Redis是什么

Redis是Remote Dictionary Server(远程数据服务)的缩写,由意大利人Antirez(Salvatore Sanfilippo)开发的一款内存高速缓存数据库,它使用C语言编写,其数据模型为key-value,并支持丰富的数据结构(类型),如stringlisthashsetsorted sort。可持久化,保证数据安全。

Redis小八卦,Salvatore Sanfilippo(antirez)是VMWare大善人聘请专心写Redis。Redis默认端口 6379 是手机按键上MERZ对应的号码,MERZ是意大利女歌手Alessia Merz梅尔兹的代名词。

Redis是一个key-value的NoSQL产品,和MemCached类似,但它存储的value类型相对更加丰富,包括string字符串、list链表、set集合、zset有序集合、hash哈希。

Redis是什么_第1张图片
Redis数据类型

与MemCached一样,为保证效率,数据都是缓存在内存中,区别是Redis会周期性把内存中的数据写入到硬盘(数据持久化、安全)。由于Redis支持的value类型众多,也被称之为结构化的NoSQL数据库。

Redis是什么_第2张图片
Redis

在开发网站的时候有些数据在短时间内不会发生变化,而他们还要被频繁访问,为了提高用户请求速度并降低站点的负载,就把这些数据放到一个读取速度更快的介质上,或通过较少的计算量就可以获得该数据,该行为就称为对数据的缓存,该截止可是文件、数据库、内存,而内存常用做数据缓存。

缓存的两种形式中,页面缓存经常用在CMS内容管理系统里,数据缓存经常用在页面里的具体数据中。例如新闻页面适合做页面缓存,商城页面比较适合分区块做数据缓存。

Redis是什么_第3张图片
数据存储类型

MySQL数据库的数据实际上以文件形式存储在硬盘里,对于web应用而言,资源瓶颈大多出现在数据库上。常用缓存(cache)分为数据缓存和页面缓存(smarty),使用缓存技术可减轻数据库的负载。

Nosql简介

web2.0时代,nosql产品非常火热,常见产品如redis/memcached/mongodb.

nosql产品的特点:不使用严格的表结构,数据查询一般都不再使用sql查询

世界上正在使用的nosql产品 www.nosql-database.org

NoSQL产品的比较

  • KV存储 redis/memcached

  • 文档存储 mongoDB(JSON)

Redis是一个KV的nosql产品,数据是在内存中存储,同时支持数据持久化操作,所以这个产品对数据完整性更加的友好.

Redis和Memcached比较

  • redis不仅仅支持简单的KV类型的数据,同时提供list、set、zset、hash等数据结构的存储。
  • redis支持master-slave主从模式应用
  • redis支持数据持久化,可将内存中数据保存到硬盘,重启后可再起加载到内存。
  • redis单个value的最大限制为1GB,memcached只能保存1MB的数据。

Redis数据类型

3.1 String 字符串类型

redis中的字符串是一个字节序列,redis中的字符串是二进制安全的,这意味着他们的长度不由任何特殊的终止字符决定.因此可在一个字符串中存储高达512MB的任何内容.

set name junchow

get name

set和get是redis命令,name是redis中使用的键名

  • set 设置键值对
  • get 通过键名获取键值
  • incr 可对某个key的value进行+1
  • decr 可对某个key的value进行-1
set age 20

get age

incr age

decr age

incrby 指定键名进行增加

incrby age 20

get age

decrby 指定键名进行减少

decrby age 20

get age

keys * 获取所有字键名

keys *

redis的key是如何设计的呢?

思考原先在mysql中数据是如何存储的

  • 将mysql表名换成key的前缀
  • 将mysql主键放在前缀后面,一般使用冒号分割.
  • 将对应记录的主键值作为key的值
  • 将mysql其他字段作为key的第四部分

例如:

// 将主键id为1名为junchow的用户保存到it表
it_user:id:1:username junchow
it_user:id:1:gender 1
it_user:id:1:email [email protected]

// 获取所有字段
keys it_user:id:1*

// 获取1号用户的姓名
get it_user:id:1:username

3.2 Hash 数据类型

//设置值
hset userinfo name junchow

//解析
hset : cmd
key: userinfo
value: name junchow

//等价于
$userinfo = array('name'=>'junchow')

//获取值
hget userinfo name

redis中的hash类型php中的关联数组

//设置多个hash值
hmset userinfo age 30 email [email protected]

//获取单个
hget userinfo age
hget userinfo email

//获取所有
hgetall userinfo

3.3 List 链表数据

链表类型类似于队列或栈的数据结构,链表可视为存储数据的容器.链表的左侧被称为头部,右侧被称为尾部.

链表可模拟出队列(先进先出),也可以模拟栈(先进后出).

//从左侧装入 lpush
lpush link1 A
lpush link1 B
Redis是什么_第4张图片
lpush.png
//从右侧转入 rpush
rpush link2 A
rpush link2 B
Redis是什么_第5张图片
rpush.png
//获取数据
lrange link1 0 -1
//lrange 表示从左侧开始获取link1中,0表示开始位置, -1表示结束位置.
B A
//从左侧弹出 lpop
lpop link1
// 从右侧弹出 rpop
rpop link1

链表数据结构在实际项目中有那些地方可以使用呢?

应用场景

后台要统计一下最近登录的10个用户,使用mysql来完成,形成这样一条sql.

SELECT * FROM user ORDER BY login_time DESC LIMIT 10;

若使用redis中的链表实现,将用户登录组件的id从左侧存入链表.

lpush loginuser alice
lpush loginuser ben
lpush loginuser carl
lpush loginuser deny
lpush loginuser elva
...

当链表中存储数据超过10个后

rpop

3.4 Set 无序集合类型

集合是数学里面常见概念,是一类无序数据的归总.集合满足三个特点:

  • 无序性:集合中的元素是没有顺序之分的
  • 唯一性:集合中的元素彼此是不能重复的
  • 确定性:集合中的元素个数是确定的

集合运算

  • 交集:集合之间公共的部分
  • 并集:集合全部的元素
  • 差集

集合命令

//向集合setvar添加元素
sadd setvar 1
sadd setvar 2
sadd setvar 3

//从集合setvar中获取元素
smembers setvar

//判断元素1是否在集合setvar中,成功返回1,失败返回0
sismember setvar 1

//从集合中移除元素,成功返回1,失败返回0
srem setvar 1

//从集合中随机弹出元素
spop setvar

//使用sunion求集合并集
sunion setvar myset

应用场景

  • QQ中好友标签
  • 社交类型网站中好友关系展示,例如好友推荐,共同好友

案例分析

1.设计4个用户

set sns_user:id:1:username alice
set sns_user:id:1:email [email protected]

set sns_user:id:2:username ben
set sns_user:id:2:email [email protected]

set sns_user:id:3:username carl
set sns_user:id:3:email [email protected]

set sns_user:id:4:username deny
set sns_user:id:4:email [email protected]

keys sns_user:id*

2.设计好友的集合

sadd set:user:id:3:friend 1
sadd set:user:id:3:friend 2

smembers set:user:id:3:friend


sadd set:user:id:2:friend 1
smembers set:user:id:2:friend

3.获取共同好友

sinter set:user:id:2:friend set:user:id:3:friend

4.获取所有好友

sunion set:user:id:2:friend set:user:id:3:friend

5.推荐好友

sdiff set:user:id:3:friend set:user:id:2:friend

3.5 Zset 有序集合类型

三大特点:

  • 有序性
  • 唯一性
  • 确定性

有序集合需要给集合中每个元素权重值

操作命令:

//添加集合元素
zadd class:php 1 asion
zadd class:php 2 mark
zadd class:php 3 lily
zadd class:php 4 jack

//获取集合元素
zrange class:php 0 -1

//获取集合内容时显示权重信息
zrange class:php 0 -1 withscores

4. PHP操作Redis

connect($host, $port) or die('redis connect fail!');

//存取KV值
$key = 'username';
$val = 'junchow';
$redis->set($key,$val);
$val = $redis->get($key);

//删除指定键
$redis->delete($key);

//若不存在键设置值
$val = 'zhoujun';
$redis->setnx($key,$val);

//判断指定键是否存在
$redis->exists($key);

//递增递减
$key = 'age';
$val = 20;
$redis->incr($key);
$redis->decr($key);

//打印测试
var_dump($redis->get($key));
?>

5. Redis安全问题

操作redis时,默认无需客户端提供认证信息,即无需密码即可对redis实现操作,这本身是非常危险的,因此有必要开启redis的认证功能.

  1. 修改/etc/redis/redis.conf
  2. 开启 requirepass foobared,默认密码为foobared
  3. 重启redis服务
sudo pkill -9 redis-server

sudo redis-server /etc/redis/redis.conf

sudo redis-cli -h 127.0.0.1 -p 6379
//成功登录后认证
auth foobared

//连接时认证
sudo redis-cli -h 127.0.0.1 -p 6379 -a foorbared

注意:由于redis.conf中的requirepass保存的是明文,所以要注意redis.conf文件的权限.

PHP操作Redis - 连接并认证

connect($host, $port);
$redis->auth($pass) or die('redis connected fail, please check password!');
?>

6. Redis 的持久化

redis为了本身数据安全和完整性,会把内存中的数据按一定方式同步到磁盘中,这个过程被称之为持久化操作.当下次再启动redis时会把磁盘上保存的数据重新加载到内存中.
常见持久化方式由两种:

  • 基于快照的方式 : redis按一定周期将内存中的数据同步到磁盘文件中
  • 基于日志文件的追加 : redis会把数据造成更改的命令记录到日志文件中,再次重启时执行日志文件中的命令,达到数据的还原.

基于快照的持久化

  1. 修改/etc/redis/redis.conf配置文件
# 若900秒内对键key进行过1次操作,则将内存数据同步到磁盘文件
save 900 1
# 若300秒内对键key进行过10次操作,则将内存数据同步到磁盘文件
save 300 10
# 若60秒内对键key进行过10000次操作,则将内存数据同步到磁盘文件
save 60 10000

redis持久化文件保存在哪里呢?

# The filename where to dump the DB
dbfilename dump.rdb

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis

保存在 /var/lib/redis/dump.rdb

可使用bgsave命令手工出发快照持久化

基于日志追加方式持久化

修改/etc/redis/redis.conf配置文件,开启基于文件追加模式的持久化.

appendonly no

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

appendonly 设置为yes,设置appendfilename追加文件的名称.

备份文件的周期

# 只要存在对redis数据造成更改的操作,都要记录到磁盘文件上
# appendfsync always
# 每秒进行一次把对redis数据造成更改的操作记录到磁盘
appendfsync everysec
# 完全交给操作系统来完成,即操作系统不繁忙的时候会把对redis进行数据造成更改的操作记录到磁盘
# appendfsync no

重启redis服务

service redis-server restart

你可能感兴趣的:(Redis是什么)