Redis总结(redis的lpush)
mhr18 2024-11-11 11:56 33 浏览 0 评论
资源列表:
http://doc.redisfans.com/
https://redis.io/commands
Redis是什么
Redis是一个开源(BSD许可)的内存中的数据结构存储,用作数据库、缓存和消息中间件。它支持多种数据结构,如字符串、哈希表、列表、无序集合、有序集合的范围查询,位图、基数统计和地理空间索引的与查询。Redis内置复制、Lua脚本、LRU回收、事务和不同级别的磁盘持久化,并通过哨兵和自动分区提供高可用性集群。
单线程结构
- 纯内存数据库,瓶颈不在内存,在于网络IO
- 单线程,避免频繁切换上下文
- 异步阻塞I/O(多路复用)
持久化
RDB(Redis DataBase)持久化
- 快照
- 优点:适合备份、还原、恢复数据快、最大化 Redis 的性能
- 缺点:两次快照间的数据会丢失、数据集比较庞大时, fork() 可能会非常耗时
AOF(Append Only File)持久化
- 日志
- 优点:数据完整性高、可读性高、可重写(重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合)
- 缺点:体积大、慢于RDB、有bug
事务
multi开启事务,exec执行事务
可以看到,redis事务实现原理是将要执行的命令,存储到一个队列中,依次执行,报错时停止并取消事务,不报错则提交事务。
例外:不会回滚的情况:
当一个事务中某一条(多条)命令加入队列不报错,执行时才会报错,则redis会忽略错误继续执行。
使用watch监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。当exec被调用时, 不管事务是否成功执行, 对所有键的监视都会被取消。或者调用unwatch手动取消监控。
管道
- pipeline通过减少客户端与redis的通信次数来实现降低往返延时时间,而且Pipeline 实现的原理是队列,而队列的原理是时先进先出,这样就保证数据的顺序性。
- 适用场景:批量操作、可靠性要求不高、
Lua脚本
Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能,从定义上来说, Redis 中的脚本本身就是一种事务, 所以任何在事务里可以完成的事, 在脚本里面也能完成。 并且一般来说, 使用脚本要来得更简单,并且速度更快。
- 通过lua脚本可以原子执行多条redis命令
- 执行lua脚本期间,会阻塞所有命令操作
使用脚本的好处
- 减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行
- 原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。换句话说,编写脚本的过程中无需担心会出现竞态条件
- 复用性,客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑
多数据库支持
默认支持16个数据库;可以理解为一个命名空间
跟关系型数据库不一样的点
- redis不支持自定义数据库名词
- 每个数据库不能单独设置授权
- 每个数据库之间并不是完全隔离的。 可以通过flushall命令清空redis实例面的所有数据库中的数据
通过 select dbid 去选择不同的数据库命名空间 。 dbid的取值范围默认是0 -15
分布式集群
Redis Cluster中,Sharding采用slot(槽)的概念,一共分成16384个槽,这有点儿类似前面讲的pre sharding思路。对于每个进入Redis的键值对,根据key进行散列,分配到这16384个slot中的某一个中。使用的hash算法也比较简单,就是CRC16后16384取模。Redis集群中的每个node(节点)负责分摊这16384个slot中的一部分,也就是说,每个slot都对应一个node负责处理。当动态添加或减少node节点时,需要将16384个槽做个再分配,槽中的键值也要迁移。当然,这一过程,在目前实现中,还处于半自动状态,需要人工介入。Redis集群,要保证16384个槽对应的node都正常工作,如果某个node发生故障,那它负责的slots也就失效,整个集群将不能工作。为了增加集群的可访问性,官方推荐的方案是将node配置成主从结构,即一个master主节点,挂n个slave从节点。这时,如果主节点失效,Redis Cluster会根据选举算法从slave节点中选择一个上升为主节点,整个集群继续对外提供服务。这非常类似服务器节点通过Sentinel监控架构成主从结构,只是Redis Cluster本身提供了故障转移容错的能力。
- redis sharding
- codis
- twemproxy
支持的数据类型、常用命令、常用场景
String
默认存储最大容量为512M
常用命令:http://doc.redisfans.com/string/set.html、http://doc.redisfans.com/string/get.html、http://doc.redisfans.com/string/incr.html、http://doc.redisfans.com/string/decr.html、http://doc.redisfans.com/string/append.html、http://doc.redisfans.com/string/strlen.html、http://doc.redisfans.com/string/mget.html、http://doc.redisfans.com/string/setnx.html
- set+get:缓存、单点登录
- bitmap:用户上线次数统计
- incr:计数器、限速器
List
有序,可重复
常用命令:http://doc.redisfans.com/list/push.html、http://doc.redisfans.com/list/rpush.html、http://doc.redisfans.com/list/lpop.html、http://doc.redisfans.com/list/rpop.html、http://doc.redisfans.com/list/llen.html、http://doc.redisfans.com/list/lrange.html、http://doc.redisfans.com/list/lrem.html、http://doc.redisfans.com/list/lset.html
- lpush+lpop:Stack(栈)
- lpush+rpop:Queue(队列)
- lpush+ltrim:Capped Collection(有限集合)
- lpush+brpop:Message Queue(消息队列)
- blpop:事件提醒(替代轮询)
Hash
不支持数据类型的嵌套
适合存储对象
常用命令:http://doc.redisfans.com/hash/hset.html、http://doc.redisfans.com/hash/hget.html、[hmset](http://doc.redisfans.com/hash/hmset
,.html)、http://doc.redisfans.com/hash/hmget.html、http://doc.redisfans.com/hash/hgetall.html、http://doc.redisfans.com/hash/hexists.html、http://doc.redisfans.com/hash/hincryby.html、http://doc.redisfans.com/hash/hsetnx.html、http://doc.redisfans.com/hash/hdel.html
Set
无序、不重复
常用命令:http://doc.redisfans.com/set/sadd.html、http://doc.redisfans.com/set/srem.html、http://doc.redisfans.com/set/smembers.html、http://doc.redisfans.com/set/sdiff.html、http://doc.redisfans.com/set/sunion.html、http://doc.redisfans.com/set/sinter.html
- sadd:标签
- sinter:交集
- sunion:并集
SortedSet
有序、不重复
常用命令:http://doc.redisfans.com/sorted_set/zadd.html、http://doc.redisfans.com/sorted_set/zrange.html
- zcount:统计信息
- zrevrange:排行榜
key
常用命令:http://doc.redisfans.com/key/expire.html、http://doc.redisfans.com/key/ttl.html
Script
常用命令:http://redisdoc.com/script/eval.html
Redis安装
安装
首先,到redis官网找到要安装的redis版本,https://redis.io/download,我们这里选用v4.0.11,依次执行下面命令:
# wget http://download.redis.io/releases/redis-4.0.11.tar.gz # tar xzf redis-4.0.11.tar.gz # cd redis-4.0.11 # make
到此安装完成,然后可以通过make test测试编译状态
# make test
无报错完成编译应该会有这样的输出:
报错:需要tcl 8.5以上来运行redis test
You need tcl 8.5 or newer in order to run the Redis test
make: *** [test] Error 1
下面安装tcl8.6.1:
# wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz # sudo tar xzvf tcl8.6.1-src.tar.gz # cd tcl8.6.1/unix/ # sudo ./configure # sudo make # sudo make install
再次运行make test,没问题之后,运行最后一步,完成安装:
# make install
直接启动:
# ./redis-server ../redis.conf
后台启动redis,只需修改redis.conf配置文件的daemonize yes,再次启动即可。
安装启动相关命令
启动redis服务器:
# ./redis-server ../redis.conf
停止redis服务:
# ./redis-cli shutdown
连接本地启动好的redis:
# redis-cli
根据ip端口连接redis:
# redis-cli -h 127.0.0.1 -p 6379
查看当前是否设置了密码
127.0.0.1:6379> config get requirepass 1) "requirepass" 2) ""
设置密码
127.0.0.1:6379> config set requirepass 123456 //密码是123456 OK
使用总结
关于key
- 建议key不要太长,不要超过1024字节,占用内存且会降低查询效率
- 建议统一命名规则,例如:String:001:zhangsan:age
使用 bitmap 实现用户上线次数统计
Bitmap 对于一些特定类型的计算非常有效。
假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户 A 上线了多少天,用户 B 上线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加 beta 测试等活动 —— 这个模式可以使用 http://doc.redisfans.com/string/setbit.html#setbit 和 http://doc.redisfans.com/string/bitcount.html#bitcount 来实现。
比如说,每当用户在某一天上线的时候,我们就使用 http://doc.redisfans.com/string/setbit.html#setbit ,以用户名作为 key ,将那天所代表的网站的上线日作为 offset 参数,并将这个 offset 上的为设置为 1 。
举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。
当要计算 peter 总共以来的上线次数时,就使用 http://doc.redisfans.com/string/bitcount.html#bitcount 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。
更详细的实现可以参考博文(墙外) http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/ 。
缓存
缓存一致性
- 先更新库数据,再删除缓存
缓存击穿和缓存雪崩
分布式锁的实现
setnx+lua实现
public class RedisTool { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; private static final Long RELEASE_SUCCESS = 1L; // 获取锁 public static boolean getLock(Jedis jedis, String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; } // 释放锁 public static boolean releaseLock(Jedis jedis, String lockKey, String requestId) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } }
抢红包,秒杀的实现
incr+lua脚本实现
参考链接:
http://doc.redisfans.com
https://blog.csdn.net/liqingtx/article/details/60330555
更多信息可以关注我的个人博客:https://www.yizhuxiaozhan.site或https://userzhao.coding.me
也欢迎关注我的公众号:yizhuxiaozhan,二维码:
相关推荐
- 如何通过 Redis 日志排查连接超时问题
-
Redis是一种高性能的内存数据存储服务,但在高并发或误配置情况下,可能会出现连接超时问题。借助Redis日志,可以快速定位并解决连接超时的根本原因。以下是具体的排查和解决步骤:1.什么是R...
- 给你1亿的Redis key,如何高效统计?
-
前言有些小伙伴在工作中,可能遇到过这样的场景:老板突然要求统计Redis中所有key的数量,你随手执行了KEYS*命令,下一秒监控告警疯狂闪烁——整个Redis集群彻底卡死,线上服务大面积瘫痪。今天...
- Redis分布式锁的安全性分析与实践指南
-
一、Redis分布式锁的核心原理Redis分布式锁通过SETNX(SetifNotExists)和EXPIRE(Expire)指令实现原子性操作,结合UUID生成唯一标识符,确保锁的互斥性和安全...
- 高可用Redis分布式锁:秒杀系统中的锁战
-
引言在分布式系统中,“程序猿的终极武器是并发控制”。当多个服务实例同时访问共享资源时,如何避免数据不一致和重复操作?答案是分布式锁。Redis凭借其高性能和原子性操作,成为实现分布式锁的首选方案。...
- Redis分布式锁(redis分布式锁解决超卖)
-
场景描述简单模拟一个高并发库存扣减场景,商品库存加载到Redis缓存,如:127.0.0.1:6379>setproduct:stock:101200无锁状态操作从缓存中获取对应商品的库存...
- Redis 分布式锁和 ZooKeeper分布式锁
-
Redis分布式锁和ZooKeeper(简称zk)分布式锁都是用来解决在分布式系统中多个节点之间竞争资源的问题。它们各自有不同的特点和适用场景。Redis分布式锁Redis实现分布式锁主要是...
- Redis vs ZooKeeper锁:高并发下的生死对决,谁才是最终赢家?
-
在分布式系统中,锁是控制资源访问的重要机制。Redis和ZooKeeper作为两种主流的分布式锁实现方案,各有优劣。本文将从原理、性能、代码实现三个维度进行硬核对比,助你做出最佳技术选型。一、原理对比...
- 说说Redis的大key(redis key大小限制)
-
一句话总结Redis大key指存储超大值(如字符串过大、集合元素过多)的键。主要成因包括:1.设计不合理,未拆分数据结构;2.业务需求(如缓存整页数据);3.数据持续积累未清理;4.使用不当的集合类型...
- PHP Laravel框架底层机制(php框架的底层原理)
-
当然可以,Laravel是最受欢迎的PHP框架之一,以优雅的语法和丰富的生态而闻名。尽管开发体验非常“高端”,它的底层其实是由一系列结构清晰、职责分明的组件构成的。下面我从整体架构、核心流程、...
- PHP性能全面优化-值得收藏(php优化网站性能)
-
PHP项目卡顿频发,老技巧失灵?隐藏漏洞竟在代码循环里。上周公司服务器突然开始卡顿,测试发现用户请求响应时间翻倍。我们先按以前学的方法做了基准测试,用AB工具压测时发现2000并发就有5%错误,换成S...
- PHP+UniApp:低成本打造外卖系统横扫App+小程序+H5全平台
-
在餐饮行业数字化转型中,外卖系统开发常面临两大痛点:高昂的开发成本(需独立开发App、小程序、H5)和多端维护的复杂性。PHP+UniApp的组合通过技术复用与跨平台能力,为中小商家和开发者提供了“降...
- 从需求到上线:PHP+Uniapp校园圈子系统源码的架构设计与性能优化
-
一、需求分析与架构设计1.核心功能需求用户体系:支持手机号/微信登录、多角色权限(学生、教师、管理员)。圈子管理:支持创建/加入兴趣圈子(如学术、电竞)、标签分类、动态发布与审核。实时互动:点赞、评...
- PHP 8.0性能翻3倍?四年亲测:这些项目升了哭晕!
-
2020年那个感恩节,当PHP8.0带着“性能翻倍”的豪言横空出世时,无数程序员连夜备份代码准备升级。四年过去了,那些宣称“性能提升3倍”的项目,真的跑出火箭速度了吗?还记得当时铺天盖地的宣传吗?“...
- 我把 Mac mini 托管到机房了:一套打败云服务器的终极方案
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:薯仔不爱吃薯仔我把我积灰的Macmini托管到机房了,有图有真相。虽然画质又渣又昏暗,但是!这就是实锤。作为开发者,谁不想拥有个自己的服...
- 从phpstudy到Docker:我用一个下午让开发效率翻倍的实战指南
-
一、为什么放弃phpstudy?上周三下午,我花了3小时将本地开发环境从phpstudy迁移到Docker,没想到第二天团队反馈:环境部署时间从2小时压缩到5分钟,跨设备协作bug减少70%。作为一个...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (83)
- php redis (97)
- redis 存储 (67)
- redis 锁 (74)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)