一,Redis 简介
Redis是一种基于键值对(key-value)的NoSQL数据库,内存中的数据结构存储系统,它可以用作, 数据库、缓存、消息中间件。
主要的数据类型包括:
String(字符串),hash(哈希),list(列表),set(集合),zset(有序集合),bitmaps(位图),GEO(地理信息定位)等。
String类型:一个String类型的value最大可以存储512M
List类型:list的元素个数最多为2^32-1个,也就是4294967295个。
使用场景:
1,基于 redis 反向命令实现先进后出的队列结构:like:rpush,lpop,基于Redis的消息队列其实就是这个原理。
2,基于 redis 同向命令实现后进先出的栈结构:like:lpush,lpop
3,基于下标操作的数组结构
4,阻塞队列
5,推荐文章列表的分页查询。
Set类型:元素个数最多为2^32-1个,也就是4294967295个。
使用场景:
1,取集合的交并差运算:共同好友
2,用户随机抽奖
- 准备key为prizevalue为:存放每位参与用户ID的Set集合。每次抽count个名额。
- a:奖品多人少:srandmember prize count,count为负数时单人可以重复中奖。
- b:奖品少人多:spop prize count,
- c:抽取之后,奖品仍在奖池,下次还能重复中。srandmember prize count
- d: 抽取之后,奖品直接从奖池拿走,不能重复中同一个奖,公司年会场景。spop prize count
3,用户系统:用户打标签。某两位用户有相同的关注内容,那么后期用来做内容精准推荐。
Hash类型:键值对个数最多为2^32-1个,也就是4294967295个。
使用场景:
存放商品明细信息,商品的浏览量,收藏量,下单量,可以通过field的自增来累计。
用户的购物车信息。
- 以客户id作为key,每位用户创建一个hash存储结构存储对应的购物车信息。
- 将商品编号作为field,购买数量作为value进行存储
- 添加商品:追加全新的field与value
- 浏览:遍历hash
- 更改数量:自增/自减,设置value值
- 删除商品:删除field
- 清空:删除key
- 全选:hgetall
- 购物车总数量:hlen
- 增加某件商品的数量:hincrby
userId1:{ “productId1”:2 “productId2”:3 }
但是购物车商品明细数据并没有得到加速,商品信息还要二次查询数据库,面向对象再优化。把商品信息和购买数量再包装一层。
userId1: { { “count_productId1”:2, “info_productId1”:"{}" }, { “count_productId2”:3, “info_productId2”:"{}" }, }
Sorted set类型:跟Set类型相似。
二,Redis 优势和优点
1,数据存储在内存中,读取和写入速度快。如果需要持久化,可以开启相关配置,数据定期保存在硬盘上。Redis能读的速度是110000次/s,写的速度是81000次/s。
2,使用单线程,避免线程竞争,也避免线程之间上下文切换消耗。
3,主节点和从节点之间可以复制,水平扩展,突破单机部署的限制
Redis和Memcached的区别
Redis和高性能键值缓存服务器Memcached进行对比,这两者都可以用来存储键值对,彼此的性能也相差无几,但是Redis相对支持更多的数据类型,除了支持键值对之外,还支持list,set,zset,hash等数据结构的存储,而Memcached只能存储普通的字符串键。
应用场景不一样:Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和Session等
三,Laravel, Lumen 安装 Redis
① 依次执行 composer 命令(注意 PHP 版本与包版本问题)
php composer.phar require predis/predis
php composer.phar require illuminate/redis
② 进入 bootstrap/app.php 文件添加
启用(默认为被注释)
$app->withFacades();
$app->withEloquent();
$app->register(Illuminate\Redis\RedisServiceProvider::class);
③ .env 文件配置
REDIS_CLIENT=predis
REDIS_PREFIX=redis_
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=123456
④ database.php 文件配置
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '10'),
'read_write_timeout' => 0,
'persistent' => true, //增加persistent是否持久化参数
],
四,常用命令
五,常见问题
laravel中使用phpredis连接redis时报Address not available,并发较大的情况下,处于TIME-WAIT状态下的TCP连接较多,客户端无法分配出新的端口,报错Address not available,
方案一:设置关闭redis.conf中timeout,read_write_timeout(修改 0)不关闭与客户端的连接,感觉这样比较耗费资源,可以适当增加timeout时间,或是在database.php里面有redis配置参数设置
'read_write_timeout' => 0,
方案二:database.php里面有redis配置参数 增加persistent是否持久化参数(如上图)
方案三:针对原生redis操作,我们可以直接更改:
$redis->connect('inst-name.redis.rds.aliyuncs.com', 6379);
$redis->auth('inst-password');
改为:
$redis->pconnect('inst-name.redis.rds.aliyuncs.com', 6379);
$redis->auth('inst-password');
关于php 使用进程中遇到的mysql 连接问题,mysql:使用laravel的purge 和reconnetc重新连接
DB::purge('mysql');
DB::reconnect('mysql');