redis数据类型php redis数据类型和数据结构

php面试题 memcache和redis的区别

Redis与Memcached的区别

为大柴旦等地区用户提供了全套网页设计制作服务,及大柴旦网站建设行业解决方案。主营业务为网站设计、成都网站设计、大柴旦网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

传统MySQL+ Memcached架构遇到的问题

实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:

1.MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。

2.Memcached与MySQL数据库数据一致性问题。

3.Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。

4.跨机房cache同步问题。

众多NoSQL百花齐放,如何选择

最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的

问题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解

决以下几种问题

1.少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。

2.海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。

3.这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。

4.Schema free,auto-sharding等。比如目前常见的一些文档数据库都是支持schema-free的,直接存储json格式数据,并且支持auto-sharding等功能,比如mongodb。

面对这些不同类型的NoSQL产品,我们需要根据我们的业务场景选择最合适的产品。

Redis适用场景,如何正确的使用

前面已经分析过,Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-

backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用

Memcached,何时使用Redis呢?

如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:

1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

2 Redis支持数据的备份,即master-slave模式的数据备份。

3 Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

抛开这些,可以深入到Redis内部构造去观察更加本质的区别,理解Redis的设计。

Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。Redis只会缓存所有的

key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability =

age*log(size_in_memory)”计

算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以

保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。同时由于Redis将内存

中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个

操作,直到子线程完成swap操作后才可以进行修改。

使用Redis特有内存模型前后的情况对比:

VM off: 300k keys, 4096 bytes values: 1.3G used

VM on: 300k keys, 4096 bytes values: 73M used

VM off: 1 million keys, 256 bytes values: 430.12M used

VM on: 1 million keys, 256 bytes values: 160.09M used

VM on: 1 million keys, values as large as you want, still: 160.09M used

从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。

这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行

批量操作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程

池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。

如果希望在海量数据的环境中使用好Redis,我相信理解Redis的内存设计和阻塞的情况是不可缺少的。

补充的知识点:

memcached和redis的比较

1 网络IO模型

Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述

字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache

coherency和锁的问题,比如,Memcached最常用的stats

命令,实际Memcached所有操作都要对这个全局变量加锁,进行计数等工作,带来了性能损耗。

(Memcached网络IO模型)

Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和select,

对于单纯只有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型实

际会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞住的。

2.内存管理方面

Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内

存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可

能会被剔除,原因可以参考Timyang的文章:

Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,Redis

跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致swap也不会剔

除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache。

3.数据一致性问题

Memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。 Redis没有提供cas 命令,并不能保证这点,不过Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。

4.存储方式及其它方面

Memcached基本只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能

Redis除key/value之外,还支持list,set,sorted set,hash等众多数据结构,提供了KEYS

进行枚举操作,但不能在线上使用,如果需要枚举线上数据,Redis提供了工具可以直接扫描其dump文件,枚举出所有数据,Redis还同时提供了持久化和复制等功能。

5.关于不同语言的客户端支持

在不同语言的客户端方面,Memcached和Redis都有丰富的第三方客户端可供选择,不过因为Memcached发展的时间更久一些,目

前看在客户端支持方面,Memcached的很多客户端更加成熟稳定,而Redis由于其协议本身就比Memcached复杂,加上作者不断增加新的功能

等,对应第三方客户端跟进速度可能会赶不上,有时可能需要自己在第三方客户端基础上做些修改才能更好的使用。

根据以上比较不难看出,当我们不希望数据被踢出,或者需要除key/value之外的更多数据类型时,或者需要落地功能时,使用Redis比使用Memcached更合适。

关于Redis的一些周边功能

Redis除了作为存储之外还提供了一些其它方面的功能,比如聚合计算、pubsub、scripting等,对于此类功能需要了解其实现原

理,清楚地了解到它的局限性后,才能正确的使用,比如pubsub功能,这个实际是没有任何持久化支持的,消费方连接闪断或重连之间过来的消息是会全部丢

失的,又比如聚合计算和scripting等功能受Redis单线程模型所限,是不可能达到很高的吞吐量的,需要谨慎使用。

总的来说Redis作者是一位非常勤奋的开发者,可以经常看到作者在尝试着各种不同的新鲜想法和思路,针对这些方面的功能就要求我们需要深入了解后再使用。

总结:

1.Redis使用最佳方式是全部数据in-memory。

2.Redis更多场景是作为Memcached的替代者来使用。

3.当需要除key/value之外的更多数据类型支持时,使用Redis更合适。

4.当存储的数据不能被剔除时,使用Redis更合适。

谈谈Memcached与Redis(一)

1. Memcached简介

Memcached是以LiveJurnal旗下Danga Interactive公司的Bard

Fitzpatric为首开发的高性能分布式内存缓存服务器。其本质上就是一个内存key-value数据库,但是不支持数据的持久化,服务器关闭之后数

据全部丢失。Memcached使用C语言开发,在大多数像Linux、BSD和Solaris等POSIX系统上,只要安装了libevent即可使

用。在Windows下,它也有一个可用的非官方版本()。Memcached

的客户端软件实现非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang,

Lua等。当前Memcached使用广泛,除了LiveJournal以外还有Wikipedia、Flickr、Twitter、Youtube和

WordPress等。

在Window系统下,Memcached的安装非常方便,只需从以上给出的地址下载可执行软件然后运行memcached.exe –d

install即可完成安装。在Linux等系统下,我们首先需要安装libevent,然后从获取源码,make make

install即可。默认情况下,Memcached的服务器启动程序会安装到/usr/local/bin目录下。在启动Memcached时,我们可

以为其配置不同的启动参数。

1.1 Memcache配置

Memcached服务器在启动时需要对关键的参数进行配置,下面我们就看一看Memcached在启动时需要设定哪些关键参数以及这些参数的作用。

1)-p num Memcached的TCP监听端口,缺省配置为11211;

2)-U num Memcached的UDP监听端口,缺省配置为11211,为0时表示关闭UDP监听;

3)-s file Memcached监听的UNIX套接字路径;

4)-a mask 访问UNIX套接字的八进制掩码,缺省配置为0700;

5)-l addr 监听的服务器IP地址,默认为所有网卡;

6)-d 为Memcached服务器启动守护进程;

7)-r 最大core文件大小;

8)-u username 运行Memcached的用户,如果当前为root的话需要使用此参数指定用户;

9)-m num 分配给Memcached使用的内存数量,单位是MB;

10)-M 指示Memcached在内存用光的时候返回错误而不是使用LRU算法移除数据记录;

11)-c num 最大并发连数,缺省配置为1024;

12)-v –vv –vvv 设定服务器端打印的消息的详细程度,其中-v仅打印错误和警告信息,-vv在-v的基础上还会打印客户端的命令和相应,-vvv在-vv的基础上还会打印内存状态转换信息;

13)-f factor 用于设置chunk大小的递增因子;

14)-n bytes 最小的chunk大小,缺省配置为48个字节;

15)-t num Memcached服务器使用的线程数,缺省配置为4个;

16)-L 尝试使用大内存页;

17)-R 每个事件的最大请求数,缺省配置为20个;

18)-C 禁用CAS,CAS模式会带来8个字节的冗余;

2. Redis简介

Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字

符串、哈希表、链表、集合、有序集合以及基于这些数据类型的相关操作。Redis使用C语言开发,在大多数像Linux、BSD和Solaris等

POSIX系统上无需任何外部依赖就可以使用。Redis支持的客户端语言也非常丰富,常用的计算机语言如C、C#、C++、Object-C、PHP、

Python、Java、Perl、Lua、Erlang等均有可用的客户端来访问Redis服务器。当前Redis的应用已经非常广泛,国内像新浪、淘

宝,国外像Flickr、Github等均在使用Redis的缓存服务。

Redis的安装非常方便,只需从获取源码,然后make make

install即可。默认情况下,Redis的服务器启动程序和客户端程序会安装到/usr/local/bin目录下。在启动Redis服务器时,我们

需要为其指定一个配置文件,缺省情况下配置文件在Redis的源码目录下,文件名为redis.conf。

php实现redis数据库指定库号迁移的方法

这篇文章主要介绍了php实现redis数据库指定库号迁移的方法,涉及对于redis数据库的操作技巧,非常具有实用价值,需要的朋友可以参考下

本文实例讲述了php实现redis数据库指定库号迁移的方法,分享给大家供大家参考。具体如下:

redis普通的数据库迁移,只能整个redis

save,或者利用主从,当然也可以安装一个redis-dump,不过比较麻烦,这里提供一种php的脚本,实现指定库号的迁移,其实也就是遍历根据存储类型,读出来,插入新库,效果是这样:

代码如下:

[root@localhost

~]#

php

1.php

1/407

101/407

201/407

301/407

401/407

PHP实例代码如下:

代码如下:

?php

$from

=

'10.0.2.52:6379/7';

$to

=

'127.0.0.1:6379/7';

$from_redis

=

redis_init($from);

$to_redis

=

redis_init($to);

$keys

=

$from_redis-keys('*');

$count

=

0;

$total

=

count($keys);

foreach($keys

as

$key){

if(++$count

%

100

==

1){

echo

"$count/$totaln";

}

$type

=

$from_redis-type($key);

switch($type){

case

Redis::REDIS_STRING:

$val

=

$from_redis-get($key);

$to_redis-set($key,

$val);

break;

case

Redis::REDIS_LIST:

$list

=

$from_redis-lRange($key,

0,

-1);

foreach($list

as

$val){

$to_redis-rPush($key,

$val);

}

break;

case

Redis::REDIS_HASH:

$hash

=

$from_redis-hGetAll($key);

$to_redis-hMSet($key,

$hash);

break;

case

Redis::REDIS_ZSET:

$zset

=

$from_redis-zRange($key,

0,

-1,

true);

foreach($zset

as

$val=$score){

$to_redis-zAdd($key,

$score,

$val);

}

break;

}

}

function

redis_init($conf){

$redis

=

new

Redis();

preg_match('/^([^:]+)(:[0-9]+)?/(.+)?/',

$conf,

$ms);

$host

=

$ms[1];

$port

=

trim($ms[2],

':');

$db

=

$ms[3];

$redis-connect($host,

$port);

$redis-select($db);

return

$redis;

}

?

希望本文所述对大家的php程序设计有所帮助。

扩展thinkphp5的redis类方法 --- 2021-10-13

thinkphp5的自带redis类方法,只有简单的读取缓存、写入缓存的基本方法,远不能满足我们业务的需求。redis本身支持五种数据类型,string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)。redis的东西就不必再介绍了,接下来还是让我一起扩展thinkphp5的redis方法吧!

说明:这就是实例化对象,包括了options配置项、handler资源句柄、tag标签。实际上这里的handler是new Redis()的对象实例。只要在外部拿到handler资源句柄,则可以对redis的操作进行扩展了。

打印结果如下:

这里需要注意的是:

一个是调thinkphp5的redis的方法,就是这样用。

一个是如果你要调用原生的redis方法

基本的用法都讲完了。

接下来就愉快的开始扩展redis方法吧。

先找到这个类

在里面添加 谈价list 列表的方法;之后可以在里面继续添加其他redis数据类型的操作方法。

php redis如何使用

开始在

PHP

中使用

Redis

前,要确保已经安装了

redis

服务及

PHP

redis

驱动,且你的机器上能正常使用

PHP。

PHP安装redis扩展

/usr/local/php/bin/phpize

#php安装后的路径

./configure

--with-php-config=/usr/local/php/bin/php-config

make

make

install

修改php.ini文件

vi

/usr/local/php/lib/php.ini

增加如下内容:

extension_dir

=

"/usr/local/php/lib/php/extensions/no-debug-zts-20090626"

extension=redis.so

安装完成后重启php-fpm

apache。查看phpinfo信息,就能看到redis扩展。

连接到

redis

服务

?php

//连接本地的

Redis

服务

$redis

=

new

Redis();

$redis-connect('127.0.0.1',

6379);

echo

"Connection

to

server

sucessfully";

//查看服务是否运行

echo

"Server

is

running:

"

.

$redis-ping();

?

执行脚本,输出结果为:

Connection

to

server

sucessfully

Server

is

running:

PONG

Redis

PHP

String(字符串)

实例

?php

//连接本地的

Redis

服务

$redis

=

new

Redis();

$redis-connect('127.0.0.1',

6379);

echo

"Connection

to

server

sucessfully";

//设置

redis

字符串数据

$redis-set("tutorial-name",

"Redis

tutorial");

//

获取存储的数据并输出

echo

"Stored

string

in

redis::

"

.

jedis.get("tutorial-name");

?

执行脚本,输出结果为:

Connection

to

server

sucessfully

Stored

string

in

redis::

Redis

tutorial

Redis

PHP

List(列表)

实例

?php

//连接本地的

Redis

服务

$redis

=

new

Redis();

$redis-connect('127.0.0.1',

6379);

echo

"Connection

to

server

sucessfully";

//存储数据到列表中

$redis-lpush("tutorial-list",

"Redis");

$redis-lpush("tutorial-list",

"Mongodb");

$redis-lpush("tutorial-list",

"Mysql");

//

获取存储的数据并输出

$arList

=

$redis-lrange("tutorial-list",

,5);

echo

"Stored

string

in

redis::

"

print_r($arList);

?

执行脚本,输出结果为:

Connection

to

server

sucessfully

Stored

string

in

redis::

Redis

Mongodb

Mysql

Redis

PHP

Keys

实例

?php

//连接本地的

Redis

服务

$redis

=

new

Redis();

$redis-connect('127.0.0.1',

6379);

echo

"Connection

to

server

sucessfully";

//

获取数据并输出

$arList

=

$redis-keys("*");

echo

"Stored

keys

in

redis::

"

print_r($arList);

?

执行脚本,输出结果为:

Connection

to

server

sucessfully

Stored

string

in

redis::

tutorial-name

tutorial-list

php中关于redis和数据库

select 查询的时候始终先查 redis 有没有,没有去查数据库,再把结果缓存起来;

update 修改完数据库内容后,同时对 redis 中缓存的数据做一下 update 更新操作,这样 select 查询 redis 的时候就是查询的最新数据;

同理,delete、insert 操作数据库后也要同时对 redis 中缓存的数据做 update 更新操作,这样 select 查询 redis 的时候就是查询的最新数据;

这样,所有的查询操作就都是对 redis 做缓存读取,可以缓解数据库的压力;


网站标题:redis数据类型php redis数据类型和数据结构
标题路径:http://pwwzsj.com/article/hjjohj.html