初识Redis

2023-05-16

什么是Redis

Remote Dictionary Server,即远程字典服务,是一款开源的、基于内存也支持持久化的key-value数据库,提供多种语言API。通常应用于需要处理大规模数据读写的场景中。

和其它关系型数据相比,其有以下优势:

  • 基于内存,读写操作性能优越,可以支持每秒十几万次的读写操作;

  • 支持集群、分布式、主动同步等配置;

  • 具备事务能力,保证了高并发场景下数据的安全和一致性。

数据结构

Redis支持五种数据结构:

  • 字符串(string):value中存储的是一个字符串,编码格式是raw或int

  • 哈希(hash):value中存储的是一个哈希映射表(hashmap),redis提供了存取该哈希表内容的接口;

  • 列表(list):value是通过一个双向链表存储;

  • 集合(set):即hashset,可以将重复的元素放入而set会自动去重,底层实现是哈希映射表(hashmap),一个value永远是null的hashmap。

  • 有序集合(zset):内部使用hashmap和跳跃表skiplist来保证数据的存储和有序。Sorted Set的实现是HashMap(element->score, 用于实现ZScore及判断element是否在集合内),和SkipList(score->element,按score排序)的混合体。SkipList有点像平衡二叉树那样,不同范围的score被分成一层一层,每层是一个按score排序的链表。

python API

1. 数据库连接

  • 直接连接

import redis
# 直接连接
red = redis.Redis(host='localhost', port=6379, db=1)
  • 连接池连接

import redis
pool = redis.ConnectionPool(host='localhost', port=6379, db=1)
red = redis.Redis(connection_pool=pool)

连接池连接原理是,通过预先创建多个连接,当进行redis操作时可以直接获取已经创建的连接进行操作,而且操作完成后不会释放,用于后续的其它redis操作;这样可以避免频繁地进行redis创建和释放,从而提高性能。

2. 数据存取

# String类型存取
red.set('key', 'value') # 默认不存在则创建,存在则修改
red.setex('key', 'value', time) # 设置过期时间,秒,px为毫秒
red.mset({'key1':'value1', 'key2':'value2'}) # 批量设置值
red.mget({'key1':'value1', 'key2':'value2'}) # 批量获取值
red.get('key') # 获取'key'对应的值
red.strlen('key') # 返回'key'对应值的长度
red.append('key', 'hello') # 在‘key’对应的值后面追加内容
# Hash类型存取,hash即一个name对应一个dic字典
red.hset('name', 'key', 'value') # 设置一对key-value,不存在则创建,存在则修改
red.hget('name', 'key')
red.hmset('name', dic)
red.hgetall('name')
red.hmget('name', 'key1', 'key2') # 批量输出键对应的值
red.hlen('name') # 获取hash键值对个数
red.hkeys('name') # 获取hash中的所有key
red.hvals('name') #获取hash中所有value
red.hexists('name', 'key') 
red.hdel('name', 'key') # 删除key对应的键值对
red.incrby('name', 'key', amount=10) # 将amount的值与hash中key对应的值相加,key不存在则创建key=amount(amount为整数)
# list类型存取,list即一个name对应一个列表
red.lpush('name', 'list_item1', 'list_item2') # 元素从list左边添加
red.rpush('name', 'list_item1', 'list_item2') # 元素从list右边添加
red.lpushx('name', 'list_item1', 'list_item2') # 当name存在时,元素从list左边添加
red.rpushx('name', 'list_item1', 'list_item2') # 当name存在时,元素从list右边添加
red.llen('name')
red.linsert('name', BEFORE/AFTER, 'item1', 'item2') # 在列表中找到第一个元素’item1‘,在他的前面插入'item2'
red.lset('name', index, value) 
red.lrem('name', value, num=0) # 删除list中的value值,num=0删除列表中所有的value值,num=2从前往后删除两个,num=-2从后向前删除两个
red.lpop('name') # 删除list左侧第一个元素,并返回
red.lindex('name', index)
red.lrange('name', start_index, end) # 分片获取list元素
red.ltrim('name', 0, 2) # 移除list中没有在该索引(0-2)之内的值
# set类型存取,set即不允许重复的列表
red.sadd('name', 'item1')
red.sadd('name', 'item1', 'item2')
red.scard('name') # 获取集合中的元素个数
red.smembers('name')
red.sdiff('name', 'name1', 'name2') # 在'name'中,且不在'name1'和'name2'的元素
red.sismember('name', 'item') # 检测’item‘是否是’name‘集合中的元素
red.smove('name1', 'name2', 'item') # 将’item‘从’name1‘中移到’name2‘中
red.spop('name') # 从集合的右侧移除一个元素其它常用操作

3. 其它常用操作

red.flushdb(asynchronous=False) # 清空当前db中的数据,默认同步
red.flushall(asynchronous=False) 

4.管道

redis默认在执行每次操作请求时都会创建和断开连接,或者去连接池申请连接和释放连接,这就需要在服务器和客户端之前反复进行TCP数据包的传送。而管道(pipeline)可以实现一次请求指定多个命令,并且默认一次pipeline是原子性操作。

import redis
​
pool = redis.ConnectionPool(host='localhost', prot=6379, decode_response=True) # decode_response=True,默认取出结果是字节,true返回字符串
red = redis.Redis(connection_pool=pool)
# 创建管道
pipe = red.pipeline()
# 向管道里注入命令
pipe.set('name', 'jane')
pipe.sadd('gender', 'male')
# 执行管道命令
pipe.execute()
​
# 命令和执行可以连起来

Redis事务

Redis事务本质上是一组命令的集合。

Redis事务不保证原子性,且没有回滚。事务中的单条命令是原子性执行的,事务中任意命令执行失败,其余命令会继续被执行。

Redis事务的三个阶段:

  1. 开始事务(MULTI)

  2. 命令入队

  3. 执行事务(EXEC)

相关指令

MULTI:标记一个事务的开始

EXEC: 执行事务中的所有命令

DISCARD: 取消事务,放弃事务中的所有命令

WATCH keyname:监视一个或多个key,如果事务执行之前被监视的key被改动,则事务将被打断(类似乐观锁)

UNWATCH: 取消watch对所有key的监控

分布式锁

分布式锁是用来解决实际应用中并发冲突的一种手段。

# 分布式锁实现
class RedisLock(object):
    def __init__(self, lock_name, identifier, expire=10):
        pool = redis.ConnectionPool(host='10.68.4.*', port='6479', password='root', db=3)
        self.conn = redis.Redis(connection_pool=pool)
        self.lock_name = lock_name
        self.identifier = identifier
        self.expire = expire
​
    # 获取锁
    def acquire_lock(self):
        if self.conn.setnx(self.lock_name, self.identifier):
            self.conn.expire(self.lock_name, self.expire)
            return self.identifier
        elif not self.conn.ttl(self.lock_name):
            self.conn.expire(self.lock_name, self.expire)
        return False
​
    # 释放锁
    def release_lock(self):
        pipe = self.conn.pipeline()
        while True:
            try:
                pipe.watch(self.lock_name)
                if pipe.get(self.lock_name) == self.identifier:
                    pipe.delete(self.self.lock_name)
                    pipe.execute()
                    return True
                pipe.unwatch()
                break
            except redis.exceptions.WatchError:
                pass
        return False
​
count = 10
def func(thread_index):
    my_lock = RedisLock('locker_name', 'ticket')
    my_lock.acquire_lock()
    print("线程:{}--得到了锁".format(thread_index))
    global count
    if count < 1:
        print("线程:{}--没抢到票,票被抢完了".format(thread_index))
    count -= 1
    my_lock.release_lock()
​
if __name__ == '__main__':
    for i in range(50):
        t = threading.Thread(target=func, args=(i,))
        t.start()

这里没有加获取锁的超时时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

初识Redis 的相关文章

  • 在 aws-elasticache 上使用 memcached 或 Redis

    我正在 AWS 上开发一个应用程序 并使用 AWS elasticache 进行缓存 我对使用 memcached 或 redis 感到困惑 我阅读了有关 redis 3 0 2 更新以及它现在如何等同于 memchached 的文章 ht
  • 无法启动redis.service:单元redis-server.service被屏蔽

    我在 ubuntu 16 04 上安装了 Redis 服务器 但是当我尝试使用启动redis服务时 sudo systemctl start redis 我收到消息 Failed to start redis service Unit re
  • 有没有办法在 ruby​​ 中重新定义 []=+

    我正在尝试编写一个简单的 DSL 针对 Redis 并且我想自己定义 I have def key val redis zadd name val key end 我想定义 def key val redis zincrby name va
  • 如何设置和获取Redis中存储的对象?

    我试图在 redis 中存储一个对象 当我获取该对象时 它似乎不起作用 I tried u User new u name blankman redis set test u x redis get test x name error 我想
  • Redis发布/订阅:查看当前订阅了哪些频道

    我目前有兴趣查看我拥有的 Redis 发布 订阅应用程序中订阅了哪些频道 当客户端连接到我们的服务器时 我们将它们注册到如下所示的通道 user user id 这样做的原因是我希望能够看到谁 在线 目前 我在不知道客户端是否在线的情况下盲
  • Laravel 所有会话 ID 与 Redis 驱动程序

    在我的应用程序中 我希望允许某些用户能够注销除他 她之外的所有其他用户 当会话驱动程序设置为文件时 我已经完成了此功能 但现在我使用 redis 作为会话驱动程序 并且我无法找到任何方法来列出所有当前会话 就像我在文件时所做的那样司机 问题
  • 如何使 Redis 缓存中数据层次结构(树)的部分内容无效

    我有一些产品数据 需要在 Redis 缓存中存储多个版本 数据由 JSON 序列化对象组成 获取普通 基本 数据的过程很昂贵 将其定制为不同版本的过程也很昂贵 因此我想缓存所有版本以尽可能进行优化 数据结构看起来像这样 BaseProduc
  • Laravel Redis 配置

    我目前正在使用 Laravel 和 Redis 创建一个应用程序 几乎一切都工作正常 我按照文档中的说明扩展了身份验证 用户可以订阅 登录 注销 我可以创建内容 所有内容都存储在 Redis 中 但我有一个问题 我无法运行 php arti
  • ServiceStack.Redis:无法连接:sPort:

    我经常得到 ServiceStack Redis 无法连接 sPort 0 或 ServiceStack Redis 无法连接 sPort 50071 或其他端口号 当我们的网站比较繁忙时 就会出现这种情况 Redis 本身看起来很好 CP
  • 将文件传递给活动作业/后台作业

    我通过标准文件输入接收请求参数中的文件 def create file params file upload Upload create file file filename img png end 但是 对于大型上传 我想在后台作业中执行
  • 为什么单个 Redis 实例不是线程安全的?

    https github com xetorthio jedis wiki Getting started https github com xetorthio jedis wiki Getting started 在多线程环境中使用Jed
  • Redis 在键过期时更新排序集

    我有一个 Redis 服务器 其中包含一组键值对和一个排序集 提供这些键值对的键的索引 键值对可以进入 已完成 状态 此时需要在 1 小时后删除它们 这可以通过在键上设置到期时间来简单地实现 但从排序集中清除它们似乎更成问题 我可以有一个过
  • 没有适用于机器人的 Laravel 会话

    我在大型 Laravel 项目和 Redis 存储方面遇到问题 我们将会话存储在 Redis 中 我们已经有 28GB 的 RAM 然而 它的运行速度仍然相对较快 达到了极限 因为我们有来自搜索引擎机器人的大量点击 每天超过 250 000
  • 如何在Redis中正确存储图片?

    决定将图像存储在Redis中 如何正确执行 现在我这样做 redis gt set image path here is the base64 image code 我不确定这是否正常 将图片存储在Redis中是完全可以的 Redis 键和
  • 在redis中存储多个嵌套对象

    我想在redis中存储多个复杂的json数据 但不知道如何 这是我的 json 结构 users user01 username ally email email protected cdn cgi l email protection u
  • .NET Core 依赖注入中的“StackExchange.Redis.ConnectionMultiplexer”应该是“AddSingleton”还是“AddScope”?

    我正在使用以下命令将 Redis 连接添加到 NET CoreStackExchange Redis 目前看起来像这样 public static IServiceCollection AddRedisMultiplexer this IS
  • Redis AOF fsync(始终)与 LSM 树

    我对日志结构化合并树 LSM 树 的理解是 它利用了附加到磁盘非常快 因为它不需要查找 这一事实 只需将更新附加到预写日志并返回到客户端即可 我的理解是 这仍然提供了立即的持久性 同时仍然非常快 我不认为 Redis 使用 LSM 树 它似
  • Redis 客户端忽略其上设置的配置选项并尝试连接到默认 IP 127.0.01

    在AWS中 我使用ElastiCache Redis服务器并使用节点作为后端和 promise redis 包 这就是我尝试连接到我的 redis 服务器端点的方法 client redis createClient host my red
  • Redis - 错误:值不是有效的浮点数

    我在 Redis 中有一个排序集 我试图通过在Python代码中使用zincrby来更新特定元素的计数器值 例如 conn zincrby usersSet float 1 user1 但它显示错误为 错误 值不是有效的浮点数 我在 cli
  • Microsoft.Extensions.Caching.Redis 选择与 db0 不同的数据库

    一个关于了解使用哪个redis数据库以及如何配置它的问题 我有一个默认值ASP NET Core Web 应用程序和默认配置的本地redis服务器 含15个数据库 通过包管理控制台我已经安装了 Install Package Microso

随机推荐

  • ARDUINO LCD显示简单的汉字、符号(二 已写成的字模和基于Python的检索系统)

    北 61 0x0A 0x0A 0x0A 0x1B 0x0A 0x0A 0x0A 0x1B 京 61 0x04 0x1F 0x0E 0x0A 0x0E 0x15 0x15 0x0C 市 61 0x04 0x1F 0x04 0x1F 0x15
  • MindSpore图像分类训练resnet50实现

    目录 一 mindspore简介 二 训练环境 三 数据集与数据加载 四 模型训练和验证 五 迁移学习 六 模型测试和导出 一 mindspore简介 MindSpore 是华为开源的全场景深度学习框架 xff0c 旨在实现易开发 高效执行
  • 最快的远程控制软件radmin的配置和使用

    Remote Administrator Radmin 是最快的远程控制软件 又因为它不被杀毒软件查杀 从而成为远程控制的首选 nbsp 一 radmin的配置 首先下载并解压Radmin2 1 解压后有七个文件 打开 配置r server
  • 介绍一个成功的 Git 分支模型

    英文原文 xff0c A successful Git branching model xff0c 翻译 xff1a 开源中国 在这篇文章中 xff0c 我提出一个开发模型 我已经将这个开发模型引入到我所有的项目里 xff08 无论在工作还
  • 浪潮服务器通过BMC远程安装系统

    浪潮服务器的BMC xff0c 类似于IBM服务器的IPMI xff0c 可以远程安装系统或者其他操作 前提 xff1a 1 带外ip xff1a 192 168 1 100 在bios的 lan channel 1 里面配置带外ip xf
  • Linux|错误集锦|prometheus Error on ingesting samples that are too old or are too far into the future的解决

    前情回顾 xff1a 二进制prometheus部署完成后 xff0c 在prometheus的web界面进行一些数据验证工作 下面这个是我已经恢复正常的 xff0c 其实是查询不到数据的 grafana也接收不到任何数据 问题排查 xff
  • 《软件工程导论》/ 第一章 软件工程学概述 / 1.3 软件生命周期

    概括地说 xff0c 软件生命周期由3个时期组成 xff0c 每个时期又进一步划分成若干个阶段 xff1a 软件定义 xff08 问题定义 可行性研究 需求分析 xff09 软件开发 xff08 总体设计 详细设计 编码和单元测试 综合测试
  • python开发PC端桌面应用

    项目场景 xff1a 很多情况下需要用很短的时间开发一款在windows上离线运行的小工具 xff0c 以便解决一些现实问题 比如公司近期有个紧急项目 xff0c 需要根据算法需求人工标注海量的地址信息 xff0c 开发周期和工具易用性上都
  • Vue和Flask实现前后端分离

    引言 近期了解了下目前比较热门的前端框架Vue js xff0c 新技能嘛 xff0c 只有实践了用起来了 xff0c 才能有比较直观的体验 因此考虑写个小demo练练手 xff0c 后端采用Flask提供几个Restfull风格的API
  • C/S架构的应用程序开发实战(一)

    项目背景 近期需要开发一个对巨量的图片数据进行车辆品牌信息标注的工具 xff0c 为了提高标注效率 xff0c 准备先通过现有车辆品牌识别的算法模型进行下预标注 xff0c 标注人员在此基础上进行审核和修改即可 另外 xff0c 需要统计出
  • Nginx服务安全漏洞修复

    1 安全漏洞说明 使用Nginx提供服务的产品 xff0c 经过安全扫描工具扫描后报出三个高风险 三个中风险安全漏洞 2 nginx版本过低自带安全漏洞 升级nginx版本到1 21 1后 xff0c 三个高风险漏洞消失 3 HTTP 信息
  • C/S架构的应用程序开发实战(二)

    后端服务 后端用python实现 xff0c 采用flask web框架 可从github上获取flasky源码 xff0c 在此基础上进行业务逻辑的实现 程序结构如下 xff1a app 业务逻辑实现代码 common 公共函数实现 这里
  • MySql安装相关

    windows安装mysql xff1a 1 获取并解压安装包 xff1a mysql 8 0 20 winx64 zip 2 配置环境变量 xff1a 3 管理员权限打开cmd xff0c 进入安装目录 xff1a H gt cd H t
  • MySql之索引

    通常小型项目涉及数据量比较小 xff0c 数据查询频率不高 xff0c 索引通常会被忽略 但当数据量较大 xff0c 涉及多个表 xff0c 查询较为频繁时 xff0c 我们需要对查询性能进行优化 xff0c 此时 xff0c 建立合适的索
  • jupyter-notebook二次开发

    背景 公司内部提供给算法人员用于模型训练的平台开发需求中提出了嵌入Jupyter Notebook模块 xff0c 而Jupyter Notebook是开源的 xff0c 方便后续对部分细节进行功能定制和优化 xff0c 需要对其进行调研
  • python中大数据文件读取

    python中大数据文件读取 python中经常会遇到读取大文件的场景 文件较小时 xff0c 我通常采用下面方法 xff0c readlines xff08 xff09 xff0c 该方法会一次性读取文件的所有行 xff0c 并将其放入l
  • Linux|奇怪的知识|locate命令---文件管理小工具

    前言 Linux的命令是非常多的 xff0c 有一些冷门的命令 xff0c 虽然很少用 xff0c 但可能会有意想不到的功能 xff0c 例如 xff0c 本文将要介绍的locate命令 xff08 平常很少会想到使用此命令 xff0c f
  • python之装饰器

    引言 软件开发中 xff0c 当需要创建高度重复的代码时 xff0c 需要寻求一种优雅的解决方案 python中的元编程即解决这类问题 xff0c 通过创建函数和类来修改 生成或包装已有的代码 装饰器就是python中用来包装函数的一种机制
  • docker容器中程序退出异常,GPU未释放

    1 问题描述 近期在docker容器中对一批数据通过算法进行清洗时 xff0c 当数据处理完成后发现进程未正常退出 xff0c GPU内存未正常释放 span class token punctuation span root 64 ai6
  • 初识Redis

    什么是Redis Remote Dictionary Server xff0c 即远程字典服务 xff0c 是一款开源的 基于内存也支持持久化的key value数据库 xff0c 提供多种语言API 通常应用于需要处理大规模数据读写的场景