科普 | Redis七大特性简介
来源:原创 时间:2017-05-02 浏览:0 次
Redis 是一个开源的、高级的键值对存储系统,经常被用作数据结构服务器,因为其支持字符串、Hash、列表、集合和有序集合等数据结构。在Laravel中使用Redis之前,需要通过Composer安装 predis/predis 包:
composer require predis/predis
配置
应用的Redis配置位于配置文件 config/database.php 。在这个文件中,可以看到包含被应用使用的Redis服务器的 redis 数组:
'redis' => [
'cluster' => false,
'default' => [ 'host' => '127.0.0.1',
'port' => 6379, 'database' => 0,
],
],
默认服务器配置可以满足开发需要,不过,你可以基于自己的环境修改该数组。配置文件中定义的每个Redis服务器需要一个名字并指定该Redis服务器使用的主机和接口。
cluster 选项告知Laravel Redis 客户端在多个Redis节点间执行客户端分片,从而形成节点池并创建大量有效的RAM。然而,客户端分片并不处理故障转移,所以,非常适合从另一个主数据存储那里获取有效的缓存数据。
此外,你可以在Redis连接定义中定义options数组值,从而允许你指定一系列Predis客户端选项。
如果Redis服务器要求认证信息,你可以通过添加 password 配置项到Redis服务器配置数组来提供密码。
注意:如果你通过PECL安装PHP的Redis扩展,需要在 config/app.php 文件中修改Redis的别名。
一、Redis七种特性
Redis的几种使用方式 Strings、Hashs、Lists、Sets、SortedSets、Pub/Sub、Transactions 也比作七种武器,为大家讲解Redis的七种特性,并列举其适合的应用场景。
1.Strings(字符串)
Redis 字符串是一个字节序列。在 Redis 中字符串是二进制安全的,这意味着它们没有任何特殊终端字符来确定长度,所以可以存储任何长度为 512 兆的字符串。
Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字。使用Strings类型,你可以完全实现目前 Memcached 的功能,并且效率更高。还可以享受Redis的定时持久化,操作日志及 Replication等功能。除了提供与 Memcached 一样的get、set、incr、decr 等操作外,Redis还提供了下面一些操作:
获取字符串长度
往字符串append内容
设置和获取字符串的某一段内容
设置及获取字符串的某一位(bit)
批量设置一系列字符串的内容
2.Hashs(哈希)
Redis哈希是键值对的集合。 Redis哈希是字符串字段和字符串值之间的映射,所以它们用来表示对象。
在Memcached中,我们经常将一些结构化的信息打包成hashmap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。
3.Lists(链表)
Redis 列表是简单的字符串列表,通过插入顺序排序。可以添加一个元素到 Redis 列表的头部或尾部。
相信略有数据结构知识的人都应该能理解其结构。使用Lists结构,我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作Lists中某一段的api,你可以直接查询,删除Lists中某一段的元素。
4.Sets(集合)
Sets 就是一个集合,集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
4.Sorted Sets(有序集合)
和Sets相比,Sorted Sets增加了一个权重参数score,使得集合中的元素能够按score进行有序排列,比如一个存储全班同学成绩的Sorted Sets,其集合value可以是同学的学号,而score就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。另外还可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
Redis的有序集合类似于 Redis 的集合,但是存储的值在集合中具有唯一性。另外有序集合的每个成员都使用分值(score)的东西,这个分值就是用于将有序集合排序,从分值最小到最大来排序。
在 Redis 有序集合添加,删除和测试成员的存在的时间复杂度为 O(1)(恒定时间,无论集合内包含元素的数量)。列表的最大长度为 232 - 1 个元素(4294967295,每个集合的元素超过四十亿)。
5.Pub/Sub(Redis发布订阅)
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。
Redis订阅和发布实现了通讯系统,发件人(在 Redis 中的术语称为发布者)发送邮件,而接收器(订户)接收它们。信息传输的链路称为通道。Redis 一个客户端可以订阅任意数量的通道。
示例
6.Transactions(Redis事务)
谁说NoSQL都不支持事务,虽然Redis的Transactions提供的并不是严格的ACID的事务(比如一串用EXEC提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),但是这个Transactions还是提供了基本的命令打包执行的功能(在服务器不出问题的情况下,可以保证一连串的命令是顺序在一起执行的,中间有会有其它客户端命令插进来执行)。Redis还提供了一个Watch功能,你可以对一个key进行Watch,然后再执行Transactions,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。
Redis事务允许一组命令在单一步骤中执行。事务有两个属性,说明如下:
在一个事务中的所有命令作为单个独立的操作顺序执行。在Redis事务中的执行过程中而另一客户机发出的请求,这是不可以的;
Redis事务是原子的。原子意味着要么所有的命令都执行,要么都不执行;
二、Redis使用示范
1.Redis HyperLogLog
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
示例
下面的例子说明了 HyperLogLog Redis 的工作原理:
redis 127.0.0.1:6379> PFADD tutorials redis
1) (integer) 1
redis 127.0.0.1:6379> PFADD tutorials mongodb
1) (integer) 1
redis 127.0.0.1:6379> PFADD tutorials mysql
1) (integer) 1
redis 127.0.0.1:6379> PFCOUNT tutorials
(integer) 3
2.Redis键
Redis 中的 keys 命令用于管理 redis 中的键。Redis keys命令使用的语法如下所示:
语法
redis 127.0.0.1:6379> COMMAND KEY_NAME
示例
redis 127.0.0.1:6379> SET yiibai redis
OK
redis 127.0.0.1:6379> DEL yiibai
(integer) 1
在上面的例子中 DEL 是一个命令,而 yiibai 是一个键。如果键被成功删除,则该命令的输出将是(整数)1,否则这将是(整数)0;
3.Redis脚本
Redis 脚本是使用Lua解释脚本用来评估(计算)。从 Redis 2.6.0 版本开始内置这个解释器。命令 EVAL 用于执行 脚本命令。
语法
EVAL命令的基本语法如下:
redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]
示例
下面的例子说明了 Redis 脚本是如何工作的:
redis 127.0.0.1:6379> EVAL return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]} 2 key1
key2 first second
1) key1
2) key2
3) first
4) second
3.Redis备份
Redis的SAVE命令用于创建当前 Redis 数据库的备份。
语法
Redis 的 SAVE 命令的基本语法如下所示:
127.0.0.1:6379> SAVE
示例
以下示例显示了如何在Redis的当前数据库中创建备份。
127.0.0.1:6379> SAVE OK
在执行此命令之后,将在 redis 目录中创建一个 dump.rdb 文件。
恢复 Redis 数据
要恢复 redis 数据只需要要将 Redis 的备份文件(dump.rdb)放到 Redis 的目录中,并启动服务器。要了解知道 Redis 目录在什么位置,可使用 CONFIG 命令,如下所示:
127.0.0.1:6379> CONFIG get dir
1) dir
2) /user/yiibai/redis-2.8.13/src
在上面的命令命令输出为 /user/yiibai/redis-2.8.13/src 就是使用的 Redis 目录,也就是 Redis 的服务器安装的目录。
4.Bgsave
创建 Redis 的备份也可以使用备用命令 BGSAVE 。此命令将启动备份过程,并在后台运行此。
示例
127.0.0.1:6379> BGSAVE Background saving started
Redis安全
Redis 数据库可以配置安全保护的,所以任何客户端在连接执行命令时需要进行身份验证。为了确保 Redis 的安全,需要在配置文件设置密码。
示例
下面给出的例子显示的步骤是用来确保 Redis 实例的安全。
127.0.0.1:6379> CONFIG get requirepass 1) requirepass 2)
默认情况下此属性是空的,这意味着此实例没有设置密码。可以通过执行以下命令来修改设置此属性
127.0.0.1:6379> CONFIG set requirepass yiibaipass
OK
127.0.0.1:6379> CONFIG get requirepass
1) requirepass
2) yiibaipass
如果客户端运行命令无需验证设置密码,那么(错误)NOAUTH 需要验证。错误将返回。因此,客户端需要使用 AUTH 命令来验证自己的身份信息。
语法
AUTH命令的基本语法如下所示:
127.0.0.1:6379> AUTH password
5.Redis性能测试
Redis的基准性能测试是通过同时运行 N 个命令以检查 Redis 性能的工具。
语法
Redis的基准测试的基本语法如下所示:
redis-benchmark [option] [option value]
示例
下面给出的示例是通过调用 100000 个(次)命令来检查 Redis。
redis-benchmark -n 100000
PING_INLINE: 141043.72 requests per second
PING_BULK: 142857.14 requests per second
SET: 141442.72 requests per second
GET: 145348.83 requests per second
INCR: 137362.64 requests per second
LPUSH: 145348.83 requests per second
LPOP: 146198.83 requests per second
SADD: 146198.83 requests per second
SPOP: 149253.73 requests per second
LPUSH (needed to benchmark LRANGE): 148588.42 requests per second
LRANGE_100 (first 100 elements): 58411.21 requests per second
LRANGE_300 (first 300 elements): 21195.42 requests per second
LRANGE_500 (first 450 elements): 14539.11 requests per second
LRANGE_600 (first 600 elements): 10504.20 requests per second
MSET (10 keys): 93283.58 requests per second
6.Redis客户端连接
如果启用了Redis 的接受配置监听,客户端可在TCP端口上与Unix套接字连接。以下操作执行后新的客户端连接被服务器接受:
客户端套接字在非阻塞状态,因为 Redis 使用复用和非阻塞I/O;
TCP_NODELAY选项设定以确保不会在连接时延迟;
创建一个可读的文件事件,以便 Redis 能够尽快收集客户端查询作为新的数据可被套接字读取;
客户端最大连接数量
在Redis的配置文件(redis.conf)有一个属性 maxclients ,它描述了可以连接到 Redis 的客户的最大数量。命令的基本语法是:
config get maxclients
1) maxclients
2) 10000
默认情况下此属性设置为 10000(取决于OS的文件标识符限制最大数量),但可以修改这个属性。
示例
在下面给出的例子我们已经设置客户端最大连接数量为 100000,在之后启动服务器:
redis-server --maxclients 100000
7.Redis管道
Redis是一个TCP服务器,支持请求/响应协议。在 redis 中一个请求完成以下步骤:
客户端发送一个查询给服务器,并从套接字中读取,通常服务器的响应是在一个封闭的方式;
服务器处理命令并将响应返回给客户端;
管道的含义求给服务器,而不等待全部响应,最后在单个步骤中读取所有响应。
管道的基本含义是:客户端可以发送多个请
示例
要检查 Redis 管道只需要启动 Redis 实例,并在终端输入以下命令。
$(echo -en PING
SET tutorial redis
GET tutorial
INCR visitor
INCR
visitor
INCR visitor
; sleep 10) | nc localhost 6379
PONG
OK
redis
:1
:2
:3
在上面的例子所示,了解使用 PING 命令连接 Redis,之后我们在 Redis 设定一个名为 tutorial 字符串值,之后拿到这个键对应的值并增加访问人数的三倍。在结果中,我们可以看到所有的命令都提交给 Redis 一次,Redis是给单步输出所有命令。
通道的好处
这种技术的好处是显着提高协议的性能。管道localhost 获得至少达到百倍的网络连接速度。
好了,本文就先说到这里,上面这些这只是Redis API的一些使用方式,可谓冰山一角,Redis就像一把瑞士军刀一样(或者是更万能的中国军铲),它创造了一系列更接近于应用场景的数据结构和API,目的在于让我们更直接的基于应用场景进行存储设计。更多的应用场景和组合式的应用还有待您自己的发掘。
三、总结
1.查询的字段加组合索引,在用户和数据库中增加缓存
2.添加索引方案:面对1~2千的并发是没有压力的,在往上则限制的瓶颈就是数据库最大连接数了,超过这个数tomcat直接报错连接被拒绝或者连接已经失效
3.缓存方案:事先把数据库的千万条数据同步到redis缓存中,瓶颈就是硬件设备性能,换上主机有几百个核心CPU,就算是千万级的并发下也可以完全无压力,带个用户很好的体验,容联的短信端口并发也是使用的这种缓存方式。
4.索引 缓存方案:缓存事先没有要查询的数据,在一万的并发下测试数据库毫无压力,程序先通过查缓存再查数据库大大减轻了数据库的压力,即使缓存不命中在一万的并发下也能正常访问,在10万并发下数据库依然没压力,但是redis服务器设置最大连接数300去处理10万的线程,4核CPU处理不过来,很多redis连接不了。我用show global status like 'Max_used_connections'查看数据库发现最大响应连接数是388,这么低所以数据库是不会挂掉的。
5.使用场景:a.几百或者2000以下并发直接加上组合索引就可以了。b.不想加索引又高并发的情况下可以先事先把数据放到缓存中,硬件设备支持下可解决百万级并发。c.加索引且缓存事先没有数据,在硬件设备支持下可解决百万级并发问题。d.不加索引且缓存事先没有数据,不可取,要80多秒才能得到结果,用户体验极差。
6.原理:其实使用了redis的话为什么数据库不会崩溃是因为redis最大连接数为300,这样数据库最大同时连接数也是300多,所以不会挂掉,至于redis为什么设置为300是因为设置的太高就会报错(连接被拒绝)或者等待超时(就算设置等待超时的时间很长也会报这个错)。