首页 > 数据库 >「路飞项目09」redis

「路飞项目09」redis

时间:2023-06-27 20:13:04浏览次数:53  
标签:hash name 09 redis value 路飞 key conn

1 Redis介绍和安装

# Redis :软件,存储数据的,速度非常快,redis是一个key-value存储系统(没有表的概念),cs架构的软件
-服务端  客户端(python作为客户端,java,go,图形化界面,命令窗口的命令)
# es:存数据的地方

# 关系型数据库和非关系型数据库
-关系型:mysql,PostgreSQL【PG】,oracle,sqlserver,db2
		-去 IOE:国产化
				-IBM---》浪潮信息,曙光,联想
				-Oracle---》数据----》达梦。。。。
				-EMC存储--》国产存储
        
-非关系型数据库(nosql):redis(缓存),mongodb(json文档数据存储),es(大数据量存储)。。。。
		-nosql 指非关系型数据库: not only sql,对关系型数据库的补充
        
# redis特点:
-开源软件,存数据,cs架构
-key-value存储 ,5大数据类型  value的类型是5种:字符串,hash(字典),列表,集合,有序集合
-速度快:
		-1 纯内存存储(核心)
		-2 使用了IO多路复用的网络模型
		-3 数据操作是单线程,避免了线程间切换,而且没有锁,也不会数据错乱
-支持持久化
-纯内存,可以存到硬盘上,防止数据丢失
-redis又被称之为 缓存数据库

1.1 安装redis

# redis 是用c语言编写的,需要在不同平台编译成可执行文件,才能在这个平台上运行
-redis 使用了io多路复用种的epoll模型,win不支持epoll
-redis官方,不支持win版本
-微软官方,就把redis改动,编译成可执行,能运行在win上,滞后 3.x版本
-第三方:5.x版本
    
# redis 官方网:https://redis.io/download/
# redis中文网:http://redis.cn
# win:3.x:https://github.com/microsoftarchive/redis/releases
# win:5.x:https://github.com/tporadowski/redis/releases/


# 安装:一路下一步
-安装完成后,在安装路径下有
		-redis-cli.exe     # mysql
		-redis-server.exe   # mysqld
		-redis.windows-service.conf  # my.ini
-并且会自动做成服务
		-服务的命令:redis-server.exe  redis.windows-service.conf
        
# mac系统:安装redis
# 通过homebrew这个mac特有的包管理工具来安装redis服务
1 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
-下载brew

2 brew search redis
-这个命令可以知道当前redis有哪些版本,从而确定自己需要安装哪个版本的redis。通过@来指定redis的版本,如其中的redis@3.2 redis@4.0等版本。没有@的redis就是最新版本的redis。

3 brew install redis 
-安装自己需要的版本,这里安装的是redis的最新版本,因为没有@。

4 redis安装位置 `/opt/homebrew/Cellar`目录下,配置文件在 `/opt/homebrew/etc`目录下

5 brew services start redis
-启动redis,brew services list  # 该命令可以看到在mac上所有服务目前的状况

'''
brew的其他一些常用的命令:
    1.启动redis服务
    brew services start redis

    2.关闭redis服务
    brew services stop redis

    3.重启redis服务
    brew services restart redis

    4.打开图形化界面(打开客户端......)
    redis-cli
'''

 一些常用的配置
    1.开机启动redis服务
    ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents

    2.使用配置文件启动redis-server
    redis-server /usr/local/etc/redis.conf

    3.停止redis服务
    redis-cli shutdown

    4. redis配置文件位置
    /usr/local/etc/redis.conf

    5.卸载redis
    brew uninstall redis 
    rm ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
    
    6.通过bin目录下的redis-server命令来启动redis服务
      cd /usr/local/Cellar/bin/6.0.5/bin
      ./redis-server


  

        
        
# 启动redis服务端
-1 命令行中  redis-server 就可以启动服务,这样启动后关闭窗口服务就停止了,不推荐
-2 命令行中,启动服务,并指定配置文件
    	redis-server 配置文件路径
-3 使用服务启动

# 客户端链接
-1 命令行客户端:
        -redis-cli  # 默认连本地的6379端口
        -redis-cli -p 6379 -h 127.0.0.1
-2 图形化客户端链接
        -1 最新版的Navicate支持链接redis了(收费的)
  
        -2 Redis Desktop Manager(https://resp.app/)  收费的  用的多  是用qt写的图形化界面
                -qt是个平台,做GUI[图形化界面]开发
        -用c写,用python写的叫pyqt5
            
-3 python的模块
    	-pip install redis
      
      
-4 macos的store下载官方RedisInsight,FREE
        

2 redis普通链接和连接池

2.1 普通链接

from redis import Redis

# conn = Redis()  # 建立redis的链接
conn = Redis(host="127.0.0.1",
             port=6379,
             db=0,decode_responses=True)  # 建立redis的链接   decode_responses=True,查询回来返回的结果是字符串类型,否则是byte格式
res = conn.get('name')  # 获取key名为name的value值
print(res)
conn.close()  # 关闭链接

2.2 连接池链接

# 一定要保证,池是单例的,以模块导入的形式做成了单例

'''
单例是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。简而言之,单例模式只允许创建一个类的实例,并提供静态方法来访问该实例,以确保该实例全局唯一并且在整个应用程序中保持一致性。这种模式经常应用于需要资源共享或避免重复资源消耗的场景中,例如线程池、配置文件、数据库连接等。
'''

'''
mysql有链接池,redis也有连接池,Django的orm链接没有连接池。Django一个请求是一个线程,4个请求就是4个数据库的连接。并发多个线程操作,会出现数据错乱或并发安全的问题吗?不会,因为mysql有行锁、表锁来控制。
'''

'''
连接池概念:为了防止客户端连接数过多导致服务挂掉,所以用连接池来限制连接数。
'''
# pool.py
import redis
POOL = redis.ConnectionPool(max_connections=100,host='127.0.0.1',port=6379,db=0, decode_responses=True)

# 导入POOL的文件
import redis
from pool import POOL # 模块导入的方式, 天然单例
# 代码同python伪多线程的连接池.py  
'''
POOL必须是单例:全局只有一个POOL对象
python有大概6种方式实现单例,最简单---》以模块导入的形式做成单例
'''


# python伪多线程的连接池.py
import redis
from threading import Thread
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, db=0, decode_responses=True, max_connections=100)

def task():
    conn = redis.Redis(connection_pool=POOL)# 以后拿到链接,是从POOL种取,如果没有可用的了,默认不阻塞,可以通过某个参数配置,设置阻塞等待
    res = conn.get('name') # 获取key名为name的value值
    print(res)
    conn.close() # 关闭链接
if __name__ == '__main__':
    # python的多线程是伪多线程
    for i in range(1000):
        t = Thread(target=task)
        t.start()


3 redis之字符串类型

# https://www.cnblogs.com/liuqingzheng/articles/9833534.html



import redis
conn = redis.Redis()

1 set(name, value, ex=None, px=None, nx=False, xx=False)
# ex,过期时间(秒)
# px,过期时间(毫秒)
# nx,如果设置为True,则只有name不存在时,当前set操作才执行, 值存在,就修改不了,执行没效果
# xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
conn.set('hobby', '篮球', ex=6)
conn.set('hobby', '篮球', px=3000)
conn.set('hobby', '足球', nx=True)
conn.set('hobby', '足球', xx=True)


2 setnx(name, value)
# 设置值,只有name不存在时,执行设置操作(添加),如果存在,不会修改
conn.setnx('hobby1', '乒乓球')  # 等同于conn.set('hobby', '足球', nx=True)


3 psetex(name, time_ms, value)
# 设置值
# 参数:
# time_ms,过期时间(数字毫秒 或 timedelta对象
conn.psetex('name',3000,'xxx')


4 mset(*args, **kwargs)
conn.mset({'name': "lqz", 'height': 183})  # 批量设置值,跟一次次设置的区别是,少了网络交互的时间


5 get(name)
res=conn.get('hobby')  # utf-8编码,一个中文占3-4个字节    GBK编码,一个中文占2个字节
print(res)


6 mget(keys, *args)
# 批量获取
res=conn.mget('name','age')
res=conn.mget(['name','age'])
print(res)


7 getset(name, value)  
# 设置新值并获取原来的值
res=conn.getset('name','彭于晏')
print(res)


8 getrange(key, start, end)
# 获取子序列(根据字节获取,非字符)
res=conn.getrange('name',0,1)  # 前闭后闭区间
print(res)


9 setrange(name, offset, value)
# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
conn.setrange('name',2,'lqz')

10 setbit(name, offset, value)
11 getbit(name, offset)
12 bitcount(key, start=None, end=None)
13 bitop(operation, dest, *keys)


14 strlen(name)
res=conn.strlen('name')  #  统计字节长度
print(res) # 9


15 incr(self, name, amount=1)  
# 做计数器。好处是不会出现并发安全问题
# 自增name对应的值,当name不存在时,则创建name=amount,否则,则自增。
# 参数:amount,自增数(必须是整数)
conn.incrby('height')


16 incrbyfloat(self, name, amount=1.0)
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。
# 参数:amount,自增数(浮点型)


17 decrby(self, name, amount=1)
# 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。
conn.decrby('height',5)


18 append(key, value) 
# 在redis key对应的值后面追加内容
conn.append('name', 'xxxx')

conn.close()


'''
get
set
strlen
append
'''

4 redis之hash类型

# hash类型就是咱们python中的字典,key-value,字典又叫hash类型。字典的key必须可hash
-字典类型在底层存储,基于数组存的 key---{key:value,key:value}
    
    
1 hset(name, key, value)
'''
name对应的hash中设置一个键值对(不存在,则创建;否则,修改)

参数:
name,redis的name
key,name对应的hash中的key
value,name对应的hash中的value

hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)
'''
conn.hset('userinfo', 'name', '渣渣辉')
conn.hset('userinfo', mapping={'age': 33, 'hobby': 'sing'})


2 hget(name,key)
# 在name对应的hash中获取根据key获取value
conn.hget('userinfo','hobby')


3 hmget(name, keys, *args)
# 在name对应的hash中获取多个key的值
# 参数:
    # name,reids对应的name
    # keys,要获取key集合,如:['k1', 'k2', 'k3']
    # *args,要获取的key,如:k1,k2,k3
conn.hmget('userinfo',['hobby','name']) 
conn.hmget('userinfo','hobby','name')


4 hgetall(name)
# 获取name对应hash的所有键值
# 慎用,如果hash中key非常多,可能会撑爆内存
conn.hgetall('userinfo') # {'name': '渣渣辉', 'age': '33', 'hobby': 'dance'}


5 hlen(name)
# 获取name对应的hash中键值对的个数
conn.hlen('userinfo') # 3


6 hkeys(name)
# 获取name对应的hash中所有的key的值
conn.hkeys('userinfo') # ['name', 'age', 'hobby']


7 hvals(name)
# 获取name对应的hash中所有的value的值
conn.hvals('userinfo') # ['渣渣辉', '33', 'dance']


8 hexists(name, key)
# 检查name对应的hash是否存在当前传入的key
conn.hexists('userinfo','sex') # False


9 hdel(name,*keys)
# 将name对应的hash中指定key的键值对删除
conn.hdel('userinfo','sex') # 1



10 hincrby(name, key, amount=1)
# 自增name对应的hash中的指定key的值,不存在则创建key=amount
# 参数:
    # name,redis中的name
    # key, hash对应的key
    # amount,自增数(整数)
conn.hincrby('userinfo','age') # 34

11 hincrbyfloat(name, key, amount=1.0)
# 自增name对应的hash中的指定key的值,不存在则创建key=amount 
# 参数:
    # name,redis中的name
    # key, hash对应的key
    # amount,自增数(浮点数)

    



12 hscan(name, cursor=0, match=None, count=None)
# 增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,【获取的数据为约等于,不一定为count,不单独用】并非一次性将数据全部获取完,从而防止内存被撑爆
 
# 参数:
    # name,redis的name
    # cursor,游标(基于游标分批取获取数据)
    # match,匹配指定key,默认None 表示所有的key
    # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
 
# 如:
    # 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
    # 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
    # ...
    # 直到返回值cursor的值为0时,表示数据已经通过分片获取完毕
res = conn.hscan('hen', cursor=0, count=10)
print(len(res[1])) # 10或者11

    
13 hscan_iter(name, match=None, count=None)
# 利用yield封装hscan创建生成器,实现分批去redis中获取所有数据
# 参数:
    # match,匹配指定key,默认None 表示所有的key
    # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
 
# 如:
    # for item in r.hscan_iter('xx'):
    #     print item
res = conn.hscan_iter('hen',count=10)
for item in res:
    print(item)
    
    
    
'''
hset
hget
hlen
'''

标签:hash,name,09,redis,value,路飞,key,conn
From: https://www.cnblogs.com/10086upup/p/17509806.html

相关文章

  • Selenium基础:cookie javascript调用 屏幕截图 09
    1、cookie操作 绕过登录get_cookies():以字典形式返回cookie所有信息get_cookies(name):返回cookie字典中key为name的值add_cookie(cookie_dict):手动添加cookie。cookie_dict为字典数据格式,cookie_dict中必须有name和value值delete_cookie(name):删除cookie字典中key为name的......
  • redis-分布式锁优化思路
    1.加锁的代码块,粒度越小越好,语句越少越好,更不容易出现"插队"的现象2.分段锁思路:以"超卖"为例,原本是待促销200件商品,一把锁,现改成10款20件商品的促销,改成10把锁,当并发小于10的时候,甚至都不需要锁,就可以并发安全......
  • redis-分布式锁样例
    redisTemplate:stringlockKey="product_101"stringclientID=UUID.randomUUID().toString()boolresult=redisTemplate.opsForValue().setIfAbsent(lockKey,clientID,10,TimeUnit.SECONDS)if(!result){return"error_code"}try{//业务逻辑......
  • python 批量删除 redis 大量数据
    #!/usr/bin/envpython#ScananddeletekeysinRedis.#Author:cdfivefromredisimportRedisimporttimedefRedisScanAndDelete(host,port,password,db,cursor,pattern,count,batch_delete_size):start_time=time.time()client=Redis(host......
  • Java使用redis-Redis是并发安全的吗?
    大家都清楚,Redis 是一个开源的高性能键值对存储系统,被开发者广泛应用于缓存、消息队列、排行榜、计数器等场景。由于其高效的读写性能和丰富的数据类型,Redis 受到了越来越多开发者的青睐。然而,在并发操作下,Redis 是否能够保证数据的一致性和安全性呢?接下来小岳将跟大家一起来探......
  • redis-分布式锁注意事项
    lockKey:商品标识value:当前线程标识1.确保每把锁同一时间能且仅能上一次setnx(setifnotexists):当锁不存在时才上锁redisTemplate.opsForValue().setIfAbsent(lockKey,value)没加上锁需要返回错误码直接让其重试2.上锁成功后,需要在之后将锁释放redisTemplate.delete(l......
  • redis分布式锁实现
    @AutowiredprivateRedisTemplate<String,String>redisTemplate;//有死锁问题,设置锁的过期时间防止死锁publicvoidincr(){Booleanlock=redisTemplate.opsForValue().setIfAbsent("lock","1111"); //setnx,只有key不存在才能设置成功......
  • redis初见
    redis介绍redis下载:1、官网:https://redis.io/-目前最稳定:6.x版本-最新版本:7.x2、中文网:http://redis.cn/download.html-上面最新只到5.x版本3、windows版本下载地址-redis官方不提供windows版本,但windows封装了一些安装包,使其可以安装在linux下......
  • 转载: redis中的bigkey问题
    reference:  https://www.modb.pro/db/459810 什么是bigkeybigkey就是rediskey/value体系中的大value问题。我们知道redis的底层数据存储结构中,有多种数据结构的实现。String:简单动态字符串List:双向链表、压缩列表 Hash:哈希表、压缩列表 SortedSet:跳表、压......
  • 基于docker部署redis
    Docker中部署redis一、在docker中拉去redis镜像dockerpullredis二、在本机给redis创建配置文件1.mkdir–p/root/docker/redis/conf2.上传redis自带的redis.conf到改目录下。注意:有可能xftp无法链接,可以先传到其他目录,在linux中移动到该目录3.编辑redis.conf配置文件3.1.把bind......