首页 > 数据库 >redis

redis

时间:2023-10-18 17:14:53浏览次数:34  
标签:name redis value key print conn

redis介绍和安装

redis 什么

-数据库就是个存数据的地方:只是不同数据库数据组织,存放形式不一样
    -mysql  关系型数据库(oracle,sqlserver,postgrasql)
    -非关系型数据(no sql):redis,mongodb,clickhouse,infludb,elasticsearch,hadoop。。。
        -没有sql:没有sql语句
        -not olny sql 不仅仅是sql 
    -redis:一款纯内存存储的非关系型数据库(数据都在内存),速度非常快

 

redis特点

https://www.cnblogs.com/liuqingzheng/articles/9833534.html
    -redis是一个key-value存储系统
    -数据类型丰富,支持5大数据类型:字符串,列表,hash(字典),集合,有序集合
    -纯内存操作
    -可以持久化:能都把内存数据,保存到硬盘上永久存储

 

redis为什么这快

-1 纯内存,减少io
    -2 使用了 io多路复用的 epoll 网络模型
    -3 数据操作是单线程,避免了线程间切换
        -多个客户端同时操作,不会存在并发安全问题

安装

-redis:最新是7,  公司里5,6比较多
    -redis:开源软件,免费的,他们不支持win
        -epoll模型不支持win
    -微软官方:基于源码修改---》编译成可执行文件
    -第三方:https://github.com/tporadowski/redis/releases/
        
    -win:下载安装包,一路下一步
        -安装目录在环境变量中:任意路径敲 redis-server   reidis-cli 都能找到
        -把redis做成了服务,以后通过服务启动即可
        
    -mac:官网下载,解压即可
    
    
    -win,mac:两个可执行文件:
        redis-server   :等同于 mysqld
        reidis-cli     :等同于mysql

redis普通连接和连接池

Python 代码作为客户端连接

安装模块

pip install redis

普通连接

from redis import Redis

conn = Redis(host="localhost",port=6379,db=0,decode_responses=True)

res=conn.get('name')

print(res)

conn.close()

连接池

import redis
# 把池写成单例----》整个项目中,只有这一个实例(对象)---》python 中实现单例的5种方式---》模块导入的方式
POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=50)

import redis
from threading import Thread

from pool import POOL
def task():

    conn = redis.Redis(connection_pool=POOL)
    print(conn.get('name'))
    conn.close()


if __name__ == '__main__':
    for i in range(10):
        t = Thread(target=task)
        t.start()

Redis字符串类型

'''
1 set(name, value, ex=None, px=None, nx=False, xx=False)
2 setnx(name, value)
3 setex(name, value, time)
4 psetex(name, time_ms, value)
5 mset(*args, **kwargs)
6 get(name)
7 mget(keys, *args)
8 getset(name, value)
9 getrange(key, start, end)
10 setrange(name, offset, value)
11 setbit(name, offset, value)
12 getbit(name, offset)
13 bitcount(key, start=None, end=None)
14 bitop(operation, dest, *keys)
15 strlen(name)
16 incr(self, name, amount=1)
# incrby
17 incrbyfloat(self, name, amount=1.0)
18 decr(self, name, amount=1)
19 append(key, value)
'''

import redis

conn = redis.Redis(decode_responses=True)
# 1 set(name, value, ex=None, px=None, nx=False, xx=False)
# conn.set('age','19') # 没有就新增,有值就修改
# conn.set('hobby','篮球',ex=5) # ex过期时间 秒
# conn.set('hobby','篮球',px=5000)# 过期时间,毫秒
# conn.set('name','彭于晏')
# conn.set('name', 'lqz', nx=True) # nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
# conn.set('name', 'lqz', xx=True) # 如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值


# 2 setnx(name, value)
# conn.setnx('name','彭于晏')

# 3 setex(name, value, time)
# conn.setex('name',5,'sdasdfs')

# 4 psetex(name, time_ms, value)
# conn.psetex('name',5000,'lqz')


# 5 mset(*args, **kwargs) 批量设置
# conn.mset({'name': 'lqz', 'age': 29, 'gender': '男'})

# 6 get(name)
# print(conn.get('name'))

# 7 mget(keys, *args)
# print(conn.mget(['name','age']))
# print(conn.mget('name','age','gender'))

# 8 getset(name, value) # 等同于 get set
# print(conn.getset('name','oooo'))

# 9 getrange(key, start, end)
# print(conn.getrange('name',1,3)) # 前闭后闭区间

# 10 setrange(name, offset, value)
# conn.setrange('name',2,'ooo') # 包含2

# 先不聊---》操作比特位---》后面聊
# 11 setbit(name, offset, value)
# conn.setbit('name',7,1) # l=[1 1 0 0 0 1 0 0 ]
# 12 getbit(name, offset)
# 13 bitcount(key, start=None, end=None)
# 14 bitop(operation, dest, *keys)


# 15 strlen(name)
# print(conn.strlen('name'))

# 16 incr(self, name, amount=1)
# conn.incr('age',2) # 自加1,单线程,没有并发安全,数据不会错乱,天然适合计数器 计数器---》日活(日活跃用户数,只要有用户登录,就+1)
# # incrby


# 17 incrbyfloat(self, name, amount=1.0)
# conn.incrbyfloat('age',1.1)

# 18 decr(self, name, amount=1)
# conn.decr('age')
# 19 append(key, value)
# conn.append('name','ooo')
conn.close()


'''
set
get
getrange
strlen
'''

 

redis hash类型

'''  hash 类型,就是咱们python中的字典类型, 数据结构:数据的组织形式  底层存储 数组---》根据key值使用hash函数得到结构,存到数组中
    字典的key值必须可hash
    字典的key值必须是不可变数据类型
    hash 类型无序,跟放的先后顺序无关的
    python 的字典是 有序的  字典+列表
1 hset(name, key, value)
2 hmset(name, mapping)
3 hget(name,key)
4 hmget(name, keys, *args)
5 hgetall(name)
6 hlen(name)
7 hkeys(name)
8 hvals(name)
9 hexists(name, key)
10 hdel(name,*keys)
11 hincrby(name, key, amount=1)
12 hincrbyfloat(name, key, amount=1.0)
13 hscan(name, cursor=0, match=None, count=None)
14 hscan_iter(name, match=None, count=None)
'''

# print(hash(1))
# print(hash('asdfasdf'))
# # print(hash([1,2,3,])) # unhashable
# print(hash((1,2,3))) # 不可变数据类型
# a={(1,2,3):8}
# print(a[(1,2,3)])



# class Person(object):
#     pass
# p=Person()
#
# a={p:'asdf'}
# print(a[p])


import redis

conn = redis.Redis(decode_responses=True)
# 1 hset(name, key, value)
# conn.hset('userinfo','name','lqz')
# conn.hset('userinfo','age','19')

# 2 hmset(name, mapping)  弃用了,统一用hset
# conn.hmset('userinfo2',{'name':'pyy',"age":33})
# conn.hset('userinfo3',mapping={'name':'xxx',"age":33})


# 3 hget(name,key)
# print(conn.hget('userinfo','name'))
# 4 hmget(name, keys, *args)
# print(conn.hmget('userinfo',['name','age']))
# print(conn.hmget('userinfo','name','age'))


# 5 hgetall(name)  # 慎用---》userinfo 对应的value值非常多,一次性拿出来,很耗时
# print(conn.hgetall('userinfo'))

# 6 hlen(name)
# print(conn.hlen('userinfo'))

# 7 hkeys(name)
# print(conn.hkeys('userinfo'))

# 8 hvals(name)
# print(conn.hvals('userinfo'))

# 9 hexists(name, key)
# print(conn.hexists('userinfo','hobby'))


# 10 hdel(name,*keys)
# conn.hdel('userinfo',['name','age'])
# conn.hdel('userinfo','name','age')

# 11 hincrby(name, key, amount=1)
# conn.hincrby('userinfo2','age')

# 12 hincrbyfloat(name, key, amount=1.0)


# 13 hscan(name, cursor=0, match=None, count=None)  # 不单独用
## 造数据
# for i in range(1000):
#     conn.hset('hash2','egg_%s'%i,'鸡蛋%s号'%i)

# count 数字是大致的 大小,如果拿了10 ,可能是9 可能是11
# res=conn.hscan('hash2',cursor=0,count=10)   # 无序,所以不是从egg_0开始的
# print(len(res[1]))


# 14 hscan_iter(name, match=None, count=None)  # 替代hgetall,一次性全取出值,如果占内存很大,会有风险 , 使用hscan_iter 分批获取值,内存占用很小
for item in conn.hscan_iter('hash2',count=10):
    print(item)

# 分批获取数据

conn.close()


'''
hset
hget
hlen  
hexists
hincrby
hscan_iter
'''

redis列表类型

'''
1 lpush(name, values)
2 rpush(name, values) 表示从右向左操作
3 lpushx(name, value)
4 rpushx(name, value) 表示从右向左操作
5 llen(name)
6 linsert(name, where, refvalue, value))
7 r.lset(name, index, value)
8 r.lrem(name, value, num)
9 lpop(name)
10 rpop(name) 表示从右向左操作
11 lindex(name, index)
12 lrange(name, start, end)
13 ltrim(name, start, end)
14 rpoplpush(src, dst)
15 blpop(keys, timeout)
16 r.brpop(keys, timeout),从右向左获取数据
17 brpoplpush(src, dst, timeout=0)

'''
import redis

conn = redis.Redis(decode_responses=True)

# 1 lpush(name, values)
# conn.lpush('girls','刘亦菲','迪丽热巴')
# conn.lpush('girls','小红')

# 2 rpush(name, values) 表示从右向左操作
# conn.rpush('girls', '小绿')


# 3 lpushx(name, value)  #  只有key存在,才能追加
# conn.lpushx('girls','小紫')
conn.lpushx('girls1', '小紫')

# 4 rpushx(name, value) 表示从右向左操作


# 5 llen(name)
# print(conn.llen('girls'))

# 6 linsert(name, where, refvalue, value))
# conn.linsert('girls', where='before', refvalue='刘亦菲', value='新刘亦菲')
# conn.linsert('girls', where='after', refvalue='刘亦菲', value='老刘亦菲')


# 7 r.lset(name, index, value)
# conn.lset('girls',0,'oooo')  # 按索引修改某个位置值

# 8 r.lrem(name, value, num)
# conn.lrem('girls',1,'刘亦菲')   # 从左侧删一个
# conn.lrem('girls',-1,'刘亦菲')   # 从右侧删一个
# conn.lrem('girls',0,'刘亦菲')   # 全删除


# 9 lpop(name)
# print(conn.lpop('girls'))  # 左侧弹出一个
# print(conn.rpop('girls')) # 右侧弹出
# 10 rpop(name) 表示从右向左操作


# 11 lindex(name, index)
# print(conn.lindex('girls',0))

# 12 lrange(name, start, end)
# print(conn.lrange('girls',1,10000)) # 前闭后闭

# 一次性把列表中数据都取出来
# print(conn.lrange('girls', 0, -1))   # 可以用-1
# print(conn.lrange('girls', 0, conn.llen('girls')))   # 可以用-1


# 13 ltrim(name, start, end)
# conn.ltrim('girls',2,4)

# 14 rpoplpush(src, dst)
# conn.rpoplpush('girls','girls')


# 15 blpop(keys, timeout)  # block:阻塞   实现分布式的系统     消息队列
res=conn.blpop('girls',timeout=5)
print(res)

# 16 r.brpop(keys, timeout),从右向左获取数据
# 17 brpoplpush(src, dst, timeout=0)


conn.close()

# utf-8 编码的 bytes格式
# b=b'\xe8\xbf\xaa\xe4\xb8\xbd\xe7\x83\xad\xe5\xb7\xb4'
# print(b.decode('utf-8'))
#
# for i in b:
#     print(bin(i))



'''
lpush
rpush
llen
lrange
lpop
'''

 案例(把redis中列表数据类型lrang使用生成器,写一个分批获取列表所有值的生成器,相当于封装成函数)

import redis

conn = redis.Redis(decode_responses=True)


def lrange_iter(conn, name, count):
    start = 0
    end = count - 1
    while True:
        values = conn.lrange(name, start, end)
        if not values:
            break
        yield from values
        start = end + 1
        end = start + count - 1


for batch in lrange_iter(conn, 'girls', count=3):
    print(bat

 redis其他操作

import redis

conn = redis.Redis(decode_responses=True)

conn.delete('gender1') # 删除keys
print(conn.exists('gender1'))  # 判断key值是否存在,0表示不存在,1表示存在
print(conn.keys(pattern='*'))  # 取出所有的key值
conn.expire('userinfo', 5)  # 设置key值存在多久,单位秒
conn.rename('userinfo3', 'userinfo')  # 修改key值名字
conn.move('hash1', 1)  # 将数据存在的位置换库,如果是同一个库会报错
print(conn.randomkey())  # 随机弹出一个数据
print(conn.type('hash')) # 查看数据的类型

redis管道

事物四大特性(关系型数据库都支持事务)

原子性:要么都成功,要么都失败
一致性:数据前后要一致
隔离性:多个事务之间相互不影响
持久性:事务一旦完成,数据永久改变

补充

redis没有专门的事务,但是可以通过其他方式来实现事物的几个特性,所以我们认为他是具备事物的。
redis要支持事务,要完成事务的几大特性,需要使用管道来支持
单实例redis是支持管道的
集群模式下,不支持管道,就不支持事务

案例(不使用管道)

一旦程序发生错误,先执行的一方减少,但另一方没有增加,不符合事务的特性:

import redis
conn=redis.Redis()

print(conn.decrby('my_money',20))
l=[0,1,2]
print(l[5])
print(conn.incrby('he_money',10))
conn.close()

以上代码打印

 

案例(使用管道)

一旦程序发生错误,双方都失败

import redis

conn = redis.Redis()

# 创建了一个管道,把命令都一个个放到管道中,先不执行,当执行execute,才执行管道中所有的命令
pipeline = conn.pipeline(transaction=True)
print(pipeline.decrby('my_money', 10))
# 我的钱扣了,写了点别的逻辑--》有可能抛异常
l = [0, 2, 3]
print(l[9])
print(pipeline.incrby('he_money', 10))
pipeline.execute()

conn.close()

以上代码结果

 Django中使用redis

通用方案

# 写一个池
import redis

POOL = redis.ConnectionPool(max_connections=20)

# 在要使用的地方,导入使用即可
def redis_demo(requset):
    conn = redis.Redis(connection_pool=POOL, decode_responses=True)
    res = conn.incrby('count')
    print(res)

    return HttpResponse(f'您是我们第:{res}个用户')

 

第三方模块

# django-redis ---》配置文件中配置即可
pip install django-redis

# 配置文件配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
            # "PASSWORD": "123",
        }
    },
}

# 在使用的位置,导入使用
from django_redis import get_redis_connection
def redis_demo(requset):
    conn = get_redis_connection()
    res = conn.incrby('count')
    print(res)

    return HttpResponse(f'您是我们第:{res}个用户')

 

django缓存

redis数据存在内存中,取放速度快,非常适合做缓存

本来数据在mysql中,每次都查询,速度慢,把查询出来的数据,暂时存储到redis(缓存),
下次请求再来,直接从redis中拿,速度就会很快

django中如何使用缓存

配置文件配置(缓存位置:内存,文件中,redis中)

ACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
                # "PASSWORD": "123",
            }
-把数据放到缓存中(放到redis中)
      from django.core.cache import cache
      cache.set(key,value可以是任意类型,过期时间)
         -redis只支持5大数据类型,可以放python的任意类型
         -本质:pickle序列化---》bytes格式---》以redis字符串的形式放在了redis中
      cache.get(key)

前后端分离

cache.set   # 存在redis
cache.get  # 取出redis数据

前后端混合

可以整站缓存 
可以要缓存一个页面
可以缓存页面中的某个位置

可以缓存的位置

内存中
本地文件中
数据库中
reids中 (咱们用的多)

 

标签:name,redis,value,key,print,conn
From: https://www.cnblogs.com/shanghaipudong/p/17770003.html

相关文章

  • Redisson 实现分布式锁
    Redisson实现分布式锁分布式锁的应用场景有哪些?实现的方式有哪几种?Redisson又是怎么实现的?1、应用场景、特点及实现方式1.1、分布式锁的应用场景主要有以下两类:提升处理效率:避免重复任务的执行,减少系统资源的浪费(例如幂等场景)。保障数据一致性:在多个微服务并发访问时,避免......
  • redis普通连接和连接池, redis字符串类型,redis hash类型, redis列表类型
    1redis普通连接和连接池......
  • 注册功能, 前端登录注册页面,前端登录功能,前端注册功能, redis介绍和安装
    1注册功能......
  • Redission并发锁报错:IllegalMonitorStateException: attempt to unlock lock, not loc
    生产上突然出现一条报错j.l.IllegalMonitorStateException:attempttounlocklock,notlockedbycurrentthreadbynodeid:1411e030-3c44-48d7-9eb6-6030022ce681thread-id:111ato.r.RedissonBaseLock.lambda$unlockAsync$2(RedissonBaseLock.java:323)......
  • Redis中的缓存雪崩、缓存击穿、缓存穿透问题
    1.什么是缓存雪崩当我们提到缓存系统中的问题,缓存雪崩是一个经常被讨论的话题。缓存雪崩是指在某一时刻发生大量的缓存失效,导致瞬间大量的请求直接打到了数据库,可能会导致数据库瞬间压力过大甚至宕机。尤其在高并发的系统中,这种情况会导致连锁反应,整个系统可能会崩溃。1.1缓存......
  • linux yum 安装redis
    安装启动redis并设置开机自动启动yuminstall-yepel-release&&sleep3&&yuminstall-yredis&&systemctlenable--nowredis查看redis服务器状态systemctlenableredis 开放防火墙端口号(若已关闭防火墙请略过)firewall-cmd--zone=public--add-port=80/t......
  • Redis的Java客户端
    Jedis以Redis命令作为方法名称,学习成本低,简单实用。但是Jedis实例是线程不安全的,多线程环境下需要基于连接池来使用lettuce(Spring默认使用)Lettuce是基于Netty实现的,支持同步、异步和响应式编程方式,并且是线程安全的。支持Redis的哨兵模式、集群模式和管道模式。RedissionRedisso......
  • redis7.2.1在windows中通过docker使用的踩坑
    原本主要是参考了这两篇文章https://blog.csdn.net/weixin_45821811/article/details/116211724https://cloud.tencent.com/developer/article/1670205但是由于都是基于linux系统下的,可能与windows有些不同。首先,在https://hub.docker.com/_/redis?tab=tagsdocker官网上找到......
  • Docker下Redis安装
    Redis是一个开源的使用ansic语言编写、遵守bsd协议、支持网络、可基于内存、分布式、可选持久性的键值对(key-value)存储数据库准备工作安装源:DockerHub默认配置文件:配置文件示例创建文件目录C:\docker\redis\dataredis.conf#不限制IP访问,局域网能够访......
  • redis基础
    一、介绍和安装1、 redis什么-数据库就是个存数据的地方:只是不同数据库数据组织,存放形式不一样 -mysql关系型数据库(oracle,sqlserver,postgrasql)-非关系型数据(nosql):redis,mongodb,clickhouse,infludb,elasticsearch,hadoop。。。 -没有sql:没有sql语句-......