Redis数据库

Redis介绍

应用场景
  • DB缓存、减少服务器压力
  • 提高系统响应时间(响应时间、延迟时间、吞吐量、并发用户量、资源利用率)
  • 做 Seccion 分离 (登陆信息)
  • 做分布式锁 (Redis)
  • 做乐观锁(Redis):任务队列(秒杀、抢红包等)
  • 冷热数据交换
  • 签到 bitmap
  • 应用排行榜 zset
优势 & 代价

优势

  • 提升用户体验
  • 减少服务器压力
  • 提升系统性能

代价

  • 额外的硬件支出
  • 高并发缓存失效
  • 缓存与数据库数据同步
  • 缓存并发竞争
缓存模式
  • Cache Aside Pattern(旁路缓存): 先读缓存、在读数据库,然后取出数据后放入缓存,同时返回响应
  • Read/Write Through Pattern : 应用程序只操作缓存,缓存操作数据库
  • Write Behind Caching Pattern : 应用程序只更新缓存
高并发的脏读
  • 先更新数据库,再更新缓存 :update与commit之间,更新缓存,commit失败,则DB与缓存数据不一致
  • 先删除缓存,再更新数据库 :update与commit之间,有新的读,缓存空,读DB数据到缓存 数据是旧的数据,commit后 DB为新数据,则DB与缓存数据不一致
  • 先更新数据库,再删除缓存(推荐):update与commit之间,有新的读,缓存空,读DB数据到缓存 数据是旧的数据,commit后 DB为新数据,则DB与缓存数据不一致,采用延时双删策略

数据库启动

# 服务端启动
redis-server.exe
./redis-server redis.conf

# 客户端启动、并连接服务端
# -h :redis 服务器的IP地址
# -p : redis实例的端口号
./redis-cli -h 127.0.0.1 -p 6379   # 默认值

# 后端服务关闭
./redis-cli shutdown

"""
redis-server :启动redis 服务
redis-cli :进入redis 命令客户端
redis-benchmark : 性能测试的工具
redis-check-aof : aof 文件进行检查的工具
redis-check-dump : rdb 文件进行检查的工具
redis-sentinel : 启动哨兵监控服务
"""

DBSIZE  # 查看当前数据库的key数量
get keys *	# 查看key的内容
FLUHSDB  # 清空当前数据库key的数量
FLUSHALL  # 清空所有库的key
exists key  # 判断key是否存在

Redis配置文件

https://www.cnblogs.com/kreo/p/4423362.html # 配置详解

https://www.cnblogs.com/kreo/p/4423362.html	# 配置详解


bind 127.0.0.1  # 默认绑定地址(只允许本机访问)
bind 0.0.0.0	# 允许所有的地址进行连接

port 6379  # redis 服务端口
	
save th DB on disk:		# 将数据存储到硬盘
save 900 1		# 900 内至少有一个数据发生了变化 即保存
save 300 10
save 60 10000

daemonize no/yes  # 设置是否后台运行

键-值

set  # 设置值  set name lcl 
get  # 获取值  get name
mset  # 设置多个值   mset name lcl age 18 sex 1
mget  # 添加多个值	mget name age sex
append   # 添加字段	append name 2 —— lcl2
del    #  删除	del name
strlen	# 返回字符串长度	 strlen age
expire	# 设置过期时间  expire name 3 
setex  name 3 lcl  #  = set name lcl  + expire name 3 


# 字符串计数功能
incr	# 增加  incr num  每次点击增加 1 ,用于库存,描述等
decr	# 减少
incrby	# 指定增加多少   incrby nnum 2  指定num 加 2
decrby	# 指定减少多少

getrange	# 获取指定区间范围内的值(类似  between...and) getrange name 0 4 获取name字符串的0-4位
setrange	# 代表从第几位位开始替换,下脚本从零开始  setrange name 5 456   从第五位开始替换
#   (0 -1 表示全部)

redis-list(单值多value)

  • List 是简单的字符串表,按照插入顺序排序,可以添加一个元素的头部(左边)或者尾部(右边),底层实际是一个链表
lpush/rpush/lrange   # 从左/从右/获取指定长度
lpush list01 1 2 3 4 5 # list01从左侧添加 1 2 3 4 5(添加后为倒序)
rpush list02 1 2 3 4 5 # list01从右侧添加 1 2 3 4 5(添加后为正序)
lrange list01 0 -1   # 获取list01中所有的值

lpop/rpop	# 移除最左/最右(从左侧移除、从右侧移除)
lpop list01	 # 从左侧移除    例如(1 2 3 4 5) 移除元素5
rpop list01   # 从左侧移除    例如(1 2 3 4 5) 移除元素1

lrange list01 0 -1  # 获取list01中所有的值
lindex list01 1 # 按照索引下标获取元素(list01表中 按照下标1 获取元素)

llen list01 # 求列表长度

lrem list01 2 1   # 在list01中删除2个1

ltrim "开始index" "结束index"   # 截取指定范围的值后在赋值给key
ltrim list01 0 2   # 截取list01 从 0 到 2 的数据在赋值给list01

rpoplpush list1 list2 # 将list01中最后一个压入list2中第一位
lrange list01 0 -1
lrange list02 0 -1
rpoplpush list1 list2 

lset list02 0 X # 将list02 中第一位换成X

linsert key before/after
linsert list01 before x php # 在 list01 中 在 X 之前加字段php

Redis- Hash数据类型

  • hash 是一个键值对集合
  • 是一个string类型的field 和value 的映射表,hash 特别适合存储对象
hset user id 11  # 设值   user {id : 11}  内部无冒号
hget user id  # 取值   返回 11
hmset user id 12 name lcl sex man  # 向user 中插入 id 、name 、sex 键值对
hmget user id name sex  # 获取 id、name、sex 的值   
hgetall user # 获取 user 中的所有键值
hdel user id  # 删除 user 中 id 的键值对
de user  # 删除 user

hlen user # 求 user 长度   user {id : 11} 
hexistes "key"  # 在key里面某个值存在返回 1,不存在返回 0

hkeys  users   #   列举users 里面的key
hvals  users	#  列举users 里面的value

redis-set(集合)

  • set 是 string类型的无序集合
sadd set01 1 2 3 4 2 3 4  # 去重添加集合元素 (1  2  3  4)
smembers set01  # 列举set01 中的元素
sismember set01 1 # 判断元素是否存在,如果存在返回1,不存在返回0

scard  # 获取集合里面的元素个数
scard set01 

srem key value
srem  # 删除集合中元素
srem set01 3 # 删除set01 中的 3
smembers set01  # 查看集合

srandmember key + "数字个数"# 随机取几个数
srandmember set02 2 # 在set02 中随机取2个数

spop key # 随机弹出
spop set01   # set01 中随机弹出1个数(删除了)

smove key1 key2
sadd set01 set03 2 # 将set01中的2 移动到set03中 

SDIFF set01 set02 # 两个集合的差集
SINTER set01 set02  # 交集
SUNION set01 set02  # 并集  返回set01 set02 中的值,去掉重复

redis-Zset(有序集合)

  • 主要用于排序(例如抖音关注粉丝列表)
# 添加数据 —— 进入集合后 会按照键的大小进行排序(默认升序)
zadd zset01 60 v1 70 v2 80 v3 90 v4 100 v5
zrange zset01 0 -1 # 查看所有值
zrange zset01 0 -1 withscores  # 取所有的内容

zrangebyscore key start end   # ----根据开始结束来取值
zrangebyscore zset01 60 70	# 取 60 -70  之间值
zrangebyscore zset01 60 (90 	# 表示不包含90
zrangebyscore zset01 60 90 limit 1 2 	# 从第一条开始截取2条,用于翻页

zrem key value	#  某score下对应的value值,作用是删除元素
zrem zset01 v1  # 根据值来做删除

zcard  zset01 # 求zset01 总条数
zcount zset01 60 90  # 求氛围在 60-90 的个数
zrank zset01 v2 # 返回1 返回对应下角标,从0开始

Redis 的python客户端

pip install redis # 安装
# 通过python连接Redis (两种写法)
r = redis.StrictRedis(host ="localhost",port=6379,db =0)
r = redis.Redis(host ="localhost",port=6379,db =0)

import redis
class RedisString(object):
	def __init__(self):
		# 写法 1
		self.r = redis.StrictRedis(host ="localhost",port=6379,db =0)
		# 写法 2
		self.r = redis.Redis(host ="localhost",port=6379,db =0)

	def string_set(self,skey,svalue):
		res = self.r.set(skey,svalue)
		print(res)   # 返回true /fa
		return res


def main():
	r = RedisString()
	r.string_set("user","lcl")


if __name__ == '__main__':
	main()

** Redis 的 java客户端 - Jedis**

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
@Test
public void testConn(){
	//与Redis建立连接 IP+port
	Jedis redis = new Jedis("192.168.127.128", 6379);
	//在Redis中写字符串 key value
	redis.set("jedis:name:1","jd-zhangfei");
	//获得Redis中字符串的值
	System.out.println(redis.get("jedis:name:1"));
	//在Redis中写list
	redis.lpush("jedis:list:1","1","2","3","4","5");
	//获得list的长度
	System.out.println(redis.llen("jedis:list:1"));
}

** Redis性能说明 **

  • 读 : 110000 次/s
  • 写 :81000 次/s
  • 长期使用,key会不断增加,Redis作为缓存使用,物理内存也会满
  • 内存与硬盘交换(swap) 虚拟内存 ,频繁IO 性能急剧下降

** Redis过期策略说明 **

  • maxmemory : 设置最大使用内存
  • expire : 对数据设置过期时间
  • 删除策略
    • 定时删除 : 设置键的时候,同时设置定时器,到期立即执行
    • 惰性删除 :key被访问时,如果发现失效,则删除键值
    • 主动删除,
      • 默认 : 不删除 : maxmemory-policy allkeys-lru
      • LRU (Least recently used) : 最近最少使用淘汰
      • LFU (Least frequently used) : 最近一段时间内使用量少则淘汰
  • 较好方案 :惰性删除 + 主动删除
  • 主数据库(master)—— 数据写入
  • 从数据库(slave)—— 数据库的读取
  • 通过配置主从数据库实现数据库的读写分离 ( 网站的读写比例一般位10 :1)
  • master 和 slave 都是一个redis实例
配置主数据库
  • 主机配置文件 — etc / redis / redis.conf 文件
bin 0.0.0.0 # 或者修改成本机IP
  • 开启主机服务
src / redis-server redis.conf
配置从数据库
  • 为从机服务配置文件 — 复制 etc / redis / redis.conf 文件
cp redis.conf slave.conf
  • 修改 redis / save.conf 文件
vim slave.conf

bind 192.168.154.131 # 从机绑定主机IP
port 6378 # 修改当前服务器的服务端口

# 设置当前服务器的复制设置(linux)
replicaof <masterip><masterport>
replicaof 192.168.154.131 6379    

# windows中设置
slaveof 192.168.154.131 6379 # 主机IP + 端口
port 6378 # 从机端口
  • 开启主机 / 从机服务
# 开启主机服务
src / redis-server redis.conf
# 开启从机服务
src / redis-server slave.conf
  • 数据操作
  • 在 master 和 slave 分别执行 info 命令,查看输出信息 进入主客户端
# 进入从的客户端
src / redis -cli -h 192.168.154.131 -p 6379  # 连接主服务器
src / redis -cli -h 192.168.154.131 -p 6378  # 连接从服务器
  • 主从数据库自动同步
# 主数据库
set name lcl
# 从数据库
get name
哨兵模式
  • 哨兵(sentinel)是 Redis高可用性解决方案
  • Sentinel实例组成集群监控 Redis集群服务器,
  • 当主服务器下线是, Sentinel可以将该主服务器下的某一个从服务器提升为主服务器进行使用
#1 安装redis5.0
mkdir redis-master
cd /var/redis-5.0.5/src/
make install PREFIX=/var/redis-ms/redis-master
cp /var/redis-5.0.5/redis.conf /var/redis-ms/redis-master/bin
#2 修改redis.conf
# 将`daemonize`由`no`改为`yes`
daemonize yes
# 默认绑定的是回环地址,默认不能被其他机器访问
# bind 127.0.0.1
# 是否开启保护模式,由yes该为no
protected-mode no


#安装redis-slaver1
mkdir redis-slaver1
cp -r /var/redis-ms/redis-master/* /var/redis-ms/redis-slaver1
#修改配置文件
vim /var/redis-ms/redis-slaver1/redis.conf
port 6380
replicaof 127.0.0.1 6379



#安装redis-slaver2
mkdir redis-slaver2
cp -r /var/redis-ms/redis-master/* /var/redis-ms/redis-slaver2
#修改配置文件
vim /var/redis-ms/redis-slaver2/redis.conf
port 6381
replicaof 127.0.0.1 6379



#安装redis-sentinel1
mkdir redis-sentinel1
cp -r /var/redis-ms/redis-master/* /var/redis-ms/redis-sentinel1
#拷贝sentinel.conf 配置文件并修改
cp /var/redis-5.0.5/sentinel.conf /var/redis-ms/redis-sentinel1
# 哨兵sentinel实例运行的端口 默认26379
port 26379
# 将`daemonize`由`no`改为`yes`
daemonize yes
# 哨兵sentinel监控的redis主节点的 ip port
# master-name 可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2
# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提
供密码
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒,改成3秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 3000
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
# 故障转移的超时时间 failover-timeout 可以用在以下这些方面:
#1. 同一个sentinel对同一个master两次failover之间的间隔时间。
#2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
#3.当想要取消一个正在进行的failover所需要的时间。
#4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
# 默认三分钟
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000


"""
启动redis-master和redis-slaver
在redis-master目录下 ./redis-server redis.conf
在redis-slaver1目录下 ./redis-server redis.conf
在redis-slaver2目录下 ./redis-server redis.conf
#启动redis-sentinel
在redis-sentinel1目录下 ./redis-sentinel sentinel.conf
在redis-sentinel2目录下 ./redis-sentinel sentinel.conf
在redis-sentinel3目录下 ./redis-sentinel sentinel.conf
"""
#查看启动状态
[root@localhost bin]# ps -ef |grep redis
root 3602 1 0 01:33 ? 00:00:00 ./redis-server *:6379
root 3647 1 0 01:37 ? 00:00:00 ./redis-server *:6380
root 3717 1 0 01:40 ? 00:00:00 ./redis-server *:6381
root 3760 1 0 01:42 ? 00:00:00 ./redis-sentinel *:26379
[sentinel]
root 3765 1 0 01:42 ? 00:00:00 ./redis-sentinel *:26380
[sentinel]
root 3770 1 0 01:42 ? 00:00:00 ./redis-sentinel *:26381
[sentinel]
root 3783 2261 0 01:42 pts/0 00:00:00 grep --color=auto redis
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值