攻克Redis之基本知识

攻克Redis之基本知识node

摘要: 【攻克Redis】Redis基本知识 发展史 Redis是一种基于键值对的Nosql数据库,Redis值能够是string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、 HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成 Redis会将全部数据都存放在内存 中,因此它的读写性能很是惊人。

1.发展史git

Redis是一种基于键值对的Nosql数据库,Redis值能够是string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、 HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成
Redis会将全部数据都存放在内存 中,因此它的读写性能很是惊人。不只如此,Redis还能够将内存的数据利 用快照和日志的形式保存到硬盘上,这样在发生相似断电或者机器故障的时 候,内存中的数据不会“丢失”
Redis提供了键过时、发布订阅、事务、流水线、Lua脚本等附加功能

2.特性github

1.速度快(10万/秒)
全部数据存放在内存中
用C语言实现,C语言“距离”操做系统更近
单线程架构,防止多线程可能产生的问题
2.基于键值对的数据结构服务器
主要提供了5种数据结构:字符串、哈希、列表、集合、有序集合
在字符串的基础之上演变 出了位图(Bitmaps)和HyperLogLog两种神奇的“数据结构”
Redis3.2版本中 加入有关GEO(地理信息定位)的功能
3.丰富的功能
提供了键过时功能,能够用来实现缓存。
提供了发布订阅功能,能够用来实现消息系统。
支持Lua脚本功能,能够利用Lua创造出新的Redis命令。
提供了简单的事务功能,能在必定程度上保证事务特性。
提供了流水线(Pipeline)功能,这样客户端能将一批命令一次性传到 Redis,减小了网络的开销。
4.简单稳定
源码代码量少
单线程模型开发简单
不须要依赖操做系统类库
5.客户端语言多
Redis提供了简单的TCP通讯协议,不少编程语言能够很方便地接入到 Redis
6.持久化
两种持久化方式:RDB和 AOF
7.主从复制
Redis提供了复制功能,实现了多个相同数据的Redis副本,复制功能是分布式Redis的基础
8.高可用和分布式redis

3.使用场景算法

能够作1. 缓存缓存提升访问速度,下降后端数据库压力,能够设置过时时间,对存储数据进行淘汰。2.排行榜系统Redis提供了列表和有序集合数据结构,合理地使用这些数据结构能够很方便地构建各类排行榜系统。3.计数器应用视频网站有播放数、电商网站有 浏览数,为了保证数据的实时性,每一次播放和浏览都要作加1的操做4. 社交网络赞/踩、粉丝、共同好友/喜爱、推送、下拉刷新等sql

  1. 消息队列系统

Redis提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,可是对于通常的消息队列功能基本能够知足。数据库

4.五种数据结构详解编程

Redis不只仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
String——字符串Hash——字典List——列表Set——集合Sorted Set——有序集合
下面咱们就来简单说明一下它们各自的使用场景:

一、Redis String类型后端

string类型的数据存储是最简单的key-value存储;

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
public function testRedis(){缓存

//string类型的数据结构
 app()->redis->set('1', 'aa');

 //根据key取出value值
 $string = app()->redis->get('1');
}
1-2.redis客户端查看结果:

1-3.string字符串的其余redis操做方法:
//普通set/get操做$redis->set('library', 'predis');​redis->get('library');echo $retval; //显示 'predis'
//setex set一个存储时效$redis->setex('str', 10, 'bar'); //表示存储有效期为10秒
//setnx/msetnx至关于add操做,不会覆盖已有值$redis->setnx('foo',12); //true$redis->setnx('foo',34); //false
//getset操做,set的变种,结果返回替换前的值$redis->getset('foo',56);//返回34
// incrby/incr/decrby/decr 对值的递增和递减$redis->incr('foo'); //foo为57$redis->incrby('foo',2); //foo为59
//exists检测是否存在某值$redis->exists('foo');//true
//del 删除$redis->del('foo');//true
//type 类型检测,字符串返回string,列表返回 list,set表返回set/zset,hash表返回hash$redis->type('foo');//不存在,返回none$redis->set('str','test');$redis->type('str'); //字符串,返回string
//append 链接到已存在字符串$redis->append('str','_123'); //返回累加后的字符串长度8,此进str为 'test_123'
//setrange 部分替换操做$redis->setrange('str',0,'abc'); //返回3,参数2为0时等同于set操做$redis->setrange('str',2,'cd');//返回4,表示从第2个字符后替换,这时'str'为'abcd'
//substr 部分获取操做$redis->substr('str',0,2);//表示从第0个起,取到第2个字符,共3个,返回'abc'
//strlen 获取字符串长度$redis->strlen('str'); //返回4
//setbit/getbit 位存储和获取$redis->setbit('binary',31,1); //表示在第31位存入1,这边可能会有大小端问题?不过不要紧,getbit 应该不会有问题$redis->getbit('binary',31); //返回1
//keys 模糊查找功能,支持*号以及?号(匹配一个字符)$redis->set('foo1',123);$redis->set('foo2',456);$redis->keys('foo*'); //返回foo1和foo2的array$redis->keys('f?o?'); //同上
//randomkey 随机返回一个key$redis->randomkey(); //多是返回 'foo1'或者是'foo2'及其它任何一存在redis的key
//rename/renamenx 对key进行更名,所不一样的是renamenx不容许改为已存在的key$redis->rename('str','str2'); //把原先命名为'str'的key改为了'str2'
//expire 设置key-value的时效性,ttl 获取剩余有效期,persist 从新设置为永久存储$redis->expire('foo', 1); //设置有效期为1秒$redis->ttl('foo'); //返回有效期值1s$redis->expire('foo'); //取消expire行为
//dbsize 返回redis当前数据库的记录总数$redis->dbsize();
二、Redis Hash表 redis中hash表存储数据,比较相似数据库中表的一条记录;2-1.hash读写实现方式:
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public function testRedis()

{//存储 hash类型 数据结构
    app()->redis->hset('goods', 'apple', '苹果');

//取出 hash表中的数据
    $hash = app()->redis->hget('goods', 'apple');
    print_r($hash);
    echo "\n";
     
    die();
}

三、Redis list列表

List数据结构是链表结构,是双向的,能够在链表左,右两边分别操做;
也能够把list当作一种队列,因此在不少时候能够用redis用做消息队列,这个时候它的做用就相似于activeMq啦;
应用案例有时间轴数据,评论列表,消息传递等等,它能够提供简便的分页,读写操做。

3-1.list 读写实现方式:
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
public function testRedis()

{//存储 list
    app()->redis->lpush('news', 'cc'); //从队列前面插入元素
    app()->redis->lpush('news', 'ee'); //从队列前面插入元素
    app()->redis->rpush('news', 'dd');//从队列后面插入元素
    $list = app()->redis->lrange('news', 0, -1);//取出list全部元素
    print_r($list);
    echo "\n";

die();
}

四、Redis Set集合

Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set 数据结构,能够存储一些集合性的数据。
好比在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。
由于 Redis 很是人性化的为集合提供了求交集、并集、差集等操做,那么就能够很是方便的实现如共同关注、共同喜爱、二度好友等功能,对上面的全部集合操做,你还可使用不一样的命令选择将结果返回给客户端仍是存集到一个新的集合中。

1.共同好友、二度好友2.利用惟一性,能够统计访问网站的全部独立 IP3.好友推荐的时候,根据 tag 求交集,大于某个 threshold 就能够推荐
4-1.set 读写实现方式:
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public function testRedis()
{//存储 set

$fans = app()->redis->sadd('fans', 'ff');
  if($fans){
      print_r('set add ff success');
  }else{
      print_r('set add ff fail');
  }
  $fans = app()->redis->sadd('fans', 'gg'); //不存在返回true
  if($fans){
      print_r('set add gg success');
  }else{
      print_r('set add gg fail');
  }
  $fans = app()->redis->sadd('fans', 'gg'); //不存在返回false
  if($fans){
      print_r('set add gg success');
  }else{
      print_r('set add gg fail');
  }
  //取出set
  $fans = app()->redis->smembers('fans');
  print_r($fans);
  echo "\n";

}

五、Redis Zset集合(Sorted Sets)

zset是set的一个升级版本,他在set的基础上增长了一个顺序属性,这一属性在添加修改元素的时候能够指定,每次指定后,zset会自动从新按新的值调整顺序。 能够对指定键的值进行排序权重的设定,它应用排名模块比较多。
好比一个存储全班同窗成绩的 Sorted Sets,其集合 value 能够是同窗的学号,而 score 就能够是其考试得分,这样在数据插入集合的时候,就已经进行了自然的排序。另外还能够用 Sorted Sets 来作带权重的队列,好比普通消息的 score 为1,重要消息的 score 为2,而后工做线程能够选择按 score 的倒序来获取工做任务,让重要的任务优先执行。
zset集合能够完成有序执行、按照优先级执行的状况;

1.zset 读写实现方式:
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
public function testRedis()
{//zset 添加元素

app()->redis->zadd('students', '1', '90');
   app()->redis->zadd('students', '2', '80');
   app()->redis->zadd('students', '3', '95');
   app()->redis->zadd('students', '7', '75');
   app()->redis->zadd('students', '5', '55');
   //取出 zset
   $zset = app()->redis->zrange('students', 0, -1);
   print_r($zset);
   echo "\n";

}

4.集群

Redis 集群是Redis 的一个分布式实现,它是一个网状结构,每一个节点都经过 TCP 链接跟其余每一个节点链接。如今来看看Redis集群实现了哪些目标?
在1000个节点的时候仍能表现得很好而且可扩展性(scalability)是线性的。集群之间使用异步复制,而且没有合并的操做。
可接受的写入安全(Write safety)级别:那些与大多数节点相连的客户端所作的写入操做,系统尝试所有都保存下来。不过仍是会有小部分写入会丢失。
可用性(Availability):在绝大多数的主节点(master node)是可达的,而且对于每个不可达的主节点都至少有一个它的从节点(slave)可达的状况下,Redis 集群仍能进行分区(partitions)操做。
那么Redis集群环境与非分布式Redis环境在功能上有没有什么不一样的呢?
集群的数据库只有0,且不支持SELECT
因为集群将键分布在不一样的槽(slot)中,因此涉及到多键值的复制操做也是不支持的,像set里的并集(unions)和交集(intersections)操做

1 集群环境介绍

本文搭建的集群环境有3个主节点,每一个主节点都有两个从节点,架构图以下

2 修改配置文件

关于集群的配置以下:

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
7

REDIS CLUSTER


cluster-enabled yes

cluster-config-file nodes-6379.conf

cluster-node-timeout 5000
cluster-enabled表示是否开启集群模式
cluster-conf-file 表示保存节点配置文件的路径
cluster-node-timeout表示节点超时时间
完整的配置文件在https://github.com/rainbowda/... ,有须要的能够去下载
3 节点配置及启动

因为采用一个服务器运行三个Redis实例,因此每一个节点的配置有些许不一样,像端口号、文件位置、文件名称等等。这里就不将每一个配置文件贴出来了,Github上有主节点和两个从节点的配置文件。
我在redis文件夹下建立一个cluster文件夹,而后在cluster文件夹下建立一个master文件,存放主节点的配置文件master.conf和一些其余文件;再而后建立两个从节点文件7001和7002,也是存放配置文件等。

mkdir cluster
cd cluster
mkdir master 7001 7002
将配置文件拷贝到相应文件夹后,根据配置文件启动Redis,这里就不在说明了。
相关文章
相关标签/搜索