redis

Redis 基础

redis是什么

redis是一个开源的、使用C语言编写、支持网络交互、可持久化的Key-Value数据库

它通常被称为数据结构服务器

数据模型

Redis的外围由一个键、值映射的字典构成。与其他非关系型数据库主要不同在于:Redis中的值的类型不仅限于字符串,还支持如下抽象数据类型:

  • 字符串结构
  • 无序集合
  • 有序集合
  • hash类型(字典类型)
  • 列表

持久化

Redis通常将全部的数据存储在内存中。2.4版本后可配置为使用虚拟内存,一部分数据集存储在硬盘上,但这个特性废弃了

目前通过两种方式实现持久化:

  • 使用快照,一种版持久耐用模式。不时的将数据集以异步方式从内存以RDB格式写入硬盘
  • 1.1版本开始使用更安全的AOF格式代替,一种只能追加的日志类型。将数据修改操作记录起来。Redis能够在后台对只可追加的记录作修改来避免无限增长的日志。

关于缓存&NoSQL

缓存

我们都常听到Redis是用于缓存,缓存也是非常必要的,提高代码的性能。除了Redis 还有一种缓存技术是 使用 Memcached 它出现的比Redis早, 功能也比较单一。

从性能上来说,也就是从缓存的命中率来说 Memcached的性能更好,但和Redis相差不大, 但是Redis所提供的功能更加强大

重要的区别:

  • Memcached 是多线程
  • Redis 是单线程

缓存命中率:终端用户访问加速节点时, 如果该节点有缓存住了要被访问的数据时就叫命中, 如果没有的话需要回原服务器取,就是没有命中。取数据的过程与用户访问是同步进行的,所以即使是重新取的新数据,用户也不会感觉有延迟。命中率=命中数/(命中数+没有命中数),缓存命中率是判断加速效果好坏的重要因素之一


NoSQL

NoSQL: 比较出名的NoSQL产品 还有 MongoDB,它是基于JSON来存储的,这样就能记录不同的记录字段的长度不同。

NoSQL 指的是 Not only SQL, 也就是不仅仅是SQL,读作N O SQL 而不是NoSQL

它一般用于高并发的读写,这样的情况传统的关系数据库搞不定,并且有高扩展(横向)、高可用的特性。
具体到 Redis 它虽然查询速度快但是结构性不强,并没有什么两全其美的东西。
应用:
缓存、任务队列、排行榜、数据过期处理、分布式集群的 Session 分离

Linux安装

方式一

yum isntall redis

安装成功后:

redis-server /etc/redis.conf 运行

方式二

下载源码后首先编译 make,为什么编译安装都造,性能好,需要有相应的 gcc 库才可以哦
然后就可以进行安装了:
make PREFIX=/usr/local/redis install
下一步拷贝 conf 配置文件到安装目录就可以了,在配置文件中最好设置为 daemonize yes
这样启动就是后台启动了,启动命令:
redis-server ./redis.conf
可以使用 ps -ef | grep -i redis 来查看是否启动成功。
关闭推荐使用:
redis-cli shutdown ,强制关闭:kill -9 pid

基础命令

除了使用 cli 自动连接,也可以手动进行连接:redis-cli -h 127.0.0.1 -p 6379
然后可以用 ping 来测试下是否正常,正常情况它会回你一个 pong


Redis 默认有 16 个数据库,以数字命名,从 0 开始,并且是不支持修改的,数量可以在配置文件中设置(database)
使用 SELECT 命令来切换数据库,例如:SELECT 0
数据库直接并不是完全隔离的,也就是说当执行 FLUSHALL 命令时,会清空所有数据库的数据,如果只想清空当前数据库的数据,要执行 FLUSHDB
并且,官方建议不设置数据库的密码,安全应该由服务器来保证(并且也不支持设置单个数据库的密码)

常用命令

KEYS

前面说过 Redis 是以键值对存储的,可以想象为一个大 Map,这个命令也就是查询键了!用法如:
KEYS * 查询所有
也可以使用通配符,有四种,? 、 * 、 [] 以及转义符号,至于什么意思,学过正则的都知道哈

EXISTS

判断 key 是否存在,存在返回 1 不存在返回 0 。

DEL

可以删除一个或者多个 key,返回的是删除键的个数,键删除了相应的值自然也删除了,删除多个以空格分开

TYPE

获得键值的数据类型,返回的值可能是 string、hash、list(列表)、set(集合)、zset(有序集合)

HELP

帮助命令,就不多说了,教给你命令怎么用,有种用法是:help 空格 [tab]

FLUSHALL

清空数据库

字符串数据类型

字符串数据类型是 Redis 最基本的数据类型了,它能存储任何形式的字符串,包括二进制数据;允许存储的数据容量最大 512 MB
存取字符串用的就是 set/get 命令了,还有一个 MGET/MSET 这个命令可以批量读取/设置值(MSET k1 v1 k2 v2)
INCR递增命令,并且会返回递增后的值,默认每次递增的是 1,如需特殊指定就是 INCRBY name 2 这样就会每次递增二,如果不存在就会先初始化为 0 然后再递增;
相应的 DECR 就是递减了,比如: DECR id 就是递减 id 这个 key,默认也是每次一,同样也可以指定递减多少,用法和上面一样;
APPEND往尾部追加内容,用在这里就是追加字符串内容,比如:APPEND name 233 ,返回是的追加后的字符串的长度。
STRLEN 获取字符串的长度,没啥可说的。
还有一个是 getset 先获取值再设置值

Hash

其结构可以比作 Python里的 dict
常用的几个命令有:
获取/存储值

hset key name1 value1
hget key name1

# 批量存储/获取
hmset key name1 value1 name2 val2
hmget key name1 name2

其他的一些指令就一起说了吧:

# 获取全面的属性和值
hgetall key

# 删除多个值,删除 key 用 del 哦
hdel key name1 name2

# 递增递减都差不多,举一个栗子,前提是 age 这个值(val)要有,并且是数字类型
hincrby key age 5

# 判断属性是否存在
hexists key name

# 属性的个数
hlen key

# 获取所有的属性名
hkeys key

# 获取所有的值
hvals key

常用的一般就是这些吧

List

同样它也有两种形式,数组的和链表的;特点和数据结构中的也一致

# 两端添加,一个是左边一个是右边
lpush key a b c  # c 就在最左边
rpush key a b c

# 两端弹出
rpop key
lpop key

# 查看list
lrange key start end
例如: lrange key 0 -1  # 左边数,第一个到最后一个

# 查看长度
llen key

# 插入到头部,如果 key 不存在就不插入,不会自动创建
lpushx key a
rpushx key a

# 删除,count 的负号表示方向
lrem key count val
lrem key 2 3  # 删除2个3
lrem key -2 1 # 从后面(负号)删除2个1
lrem key 0 2  # 删除所有的2

# 修改值
lset key 3 v  # 在第四个位置修改为 v;从 0 开始数

# 插入
linsert key before b ll  # 在 b 的前面插入 ll
linsert key after b ll

# 其他
rpoplpush key1 key2  # 把 key1 的右边弹出,添加到 key2 的左边

push 返回的是长度,pop 返回的是弹出的元素,rpoplpush 这种命令非常适合用于 MQ

Set

相当于无序的 List,并且是唯一的
常用的命令有:

# 添加删除
sadd key a b c
srem key c

# 查看值
smembers key 

# 是否存在?存在返回 1,不存在返回 0
sismember key a

# 相差比较,和顺序有关
sdiff key1 key2

# 求交集、并集
sinter k1 k2
sunion k1 k2

# 查看数量
scard key

# 获取一个随机值
srandmember key

# 其他
sdiffstore k1 k2 k3   # k2 和 k3 的交集存到 k1
sunionstore k1 k2 k3  # k2 和 k3 的并集存到 k1

在做并集交集的处理时非常有优势,因为服务器端的聚合效率更高

Sorted-set

它存的都是字符串的内容,并且有一个分数与之关联,可用来排序,分数是可重复的,值不可以

# 增加、删除数据(返回插入元素的个数,已有的值分数会被覆盖)
zadd key 10 n1 20 n2
zrem key n1 n2

# 获取分数
zscore key name

# 获取成员的数量
zcard key

# 范围查找
zrange key 0 -1
zrange key 0 -1 withscores  # 显示分数
zrevrange key 0 -1  # 从大到小进行排序,默认是从小到大

# 按照范围删除(插入顺序)
zremrangebyrank key 0 4

# 按照分数的范围删除
zremrangebyscore 80 100

# 按照分数排序
zrangebyscore key 0 100
zrangebyscore key 0 100 withscores limit 0 2  # 显示部分数据

# 操作分数
zincrby key 3 name  # 给 name 的分数 +3

# 计算区间,80-90 之间有几个
zcount key 80 90

可以用来做热点话题和游戏排名之类的

生存时间

前面说过,Redis 基本是用来做缓存的,并且它是基于内存的,所以当然有必要设置生存时间了;
设置生存时间(PEXPIRE 可以设置毫秒):
EXPIRE Key seconds
然后可以使用 TTL 来查询,返回的是剩余的生存时间,单位是秒;如果是没有限制返回的是 -1;数据已删除是 -2
清除生存时间(重新设置值也会清除生存时间):
PERSIST key

关于集群

现在一般有两种,一种是官方的,一种是分片式的,当然是官方的好了,但是由于在 3.0+ 的版本官方才支持,所以在以前都是玩分片式的集群

分片式集群

原理其实就是计算 key 的哈希值来进行存储(到相应的 Redis 数据库),这样就会有一个问题:无法动态的增加、减少服务节点,因为毕竟节点的数量涉及到哈希的计算,其实在读取的时候也会涉及到哈希的计算,要不然它怎么知道去那一台找

官方提供的集群

需要 3.0 + 的版本哦,并且需要前面的主从复制知识
如果是在一台机器上测试,只需要拷贝不同的配置文件,然后启动的时候到相应的目录指定即可
设置集群主要是在配置文件开启:

# 开启集群
cluster-enabled yes
# 指定集群的配置文件
cluster-config-file "nodes-xxxx.conf"

然后就是使用一个官方提供的 Ruby 脚本,运行下就好了。
分布式的原理为通过插槽的分配确定存储位置,特点有:

  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
  • 节点的fail是通过集群中超过半数的节点检测失效时才生效
  • 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • redis-cluster把所有的物理节点映射到[0-16383] slot(插槽)上, cluster 负责维护 node <–>slot <–> value

一般情况插槽会平均分配到各个 Redis,存储数据的时候根据 key 来计算插槽值(当 key 有闭合的大括号时,大括号中的数据为有效值),然后做相应的存储,这样就需要在使用客户端的时候加一个 -c 的命令,设置为自动跟踪重定向,也就是当插槽值不在当前数据库时自动切换,所以直连一个就可以了

当一半以上的服务器 PING 不通某一个服务器(当一个服务器 PING 不通就将其标记为疑似下线),这个服务器就会被标记为下线,同时插槽出现空档,整个集群被标记为不可用。
解决方案可以和前面的主从联系起来,将每个节点设置为主从架构,这样就能保证高可用和负载均衡。
集群中的节点只能使用 0 号数据库,切换数据库(SELECT)会报错

Python中使用Redis

安装

pip isntall redis

创建连接

import redis
conn = redis.Redis(host='127.0.0.1', port=6379, password='...')

具体的调用和正常Redis调用一致

在Django中使用Redis

安装

pip isntall django-redis

配置

settings.py

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": "...",
        }
    },
    ...(这里可以配置多个)
}
# 3.设置redis存储django的session信息
# SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# SESSION_CACHE_ALIAS = "default"

获取连接

conn = get_redis_connection('default')

之后的用法与Redis相同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值