前言思考
整个网站的瓶颈是什么?
- 数据量如果太大、一台机器放不下了
- 数据的索引(B+ Tree),一个机器内存也放不下
- 访问量(读写混合),一个服务器承受不了
2、Memcached(缓存)+ MYSQL + 垂直拆分(读写分离)
3、分库分表 + 水平拆分 + MYSQL集群
redis入门
概述
Redis是什么?
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
Redis能干嘛?
- 内存储存、持久化,内存中是断电即失,所以说持久化很重要(rdb、aof)
- 效率高,可用于高速缓存
- 发布订阅
- 地图信息分析
- 计时器、计数器
- ………………
特性
- 多样的数据类型
- 持久化
- 集群
- 事务
通过指定的配置文件启动服务
redis-server kcongfig/redis.conf
redis是单线程
明白Redis是很快的,官方表示,Redis是基于内存操作,CPU不是Redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程来实现,就使用单线程了!
Redis是C语言写的,官方提供的数据为100000+的QPS,完全不比同样是使用key-vale的Memecache差Redis为什么单线程还这么快?
误区1:高性能的服务器一定是多线程的?
误区2∶多线程(CPU上下文会切换! )一定比单线程效率高!
先去CPU>内存>硬盘的速度要有所了解!
核心: redis是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换︰耗时的操作!!! ),对于内存系统来说,如果没有上下文切换效率就是最高的!多次读写都是在一个CPU上的,在内存情况下,这个就是最佳的方案!
setex key 30 "hello" # 设置过期时间
setnx # 不存在,再设置(在分布式锁中会常常使用)
mset # 批量设置
mget # 批量获取
msetnx # 原子性操作,要么一起成功,要么一起失败
getset # 先get然后set
# set中的值是不能重复
sadd
SISMEMBER # 判断某一个值是不是在set中
SMEBERS # 查看指定set的所有值
scard myset # 获取set集合中内容元素的个数
srem # 移除set中指定的元素
SRANDNEMBER # 随机抽选出一个元素
smove # 将一个指定的值,移动到另外一个set集合
SDIFF # 查看两个set集合中的差集
SINTER # 查看两个set集合中的交集
SUNION # 查看两个set集合的并集
# Hash(哈希)
hset
hget
hmset
hmget
hdel # 删除hash指定key字段!对应的value值也就消失了
HEXISTS # 判断hash指定的字段是否存在
hkeys # 只获取所有的key
hvals # 只获取所有的value
# Zset(有序集合)
# 在set的基础上
Hyperloglog
什么是基数?
不重复的元素(个数)
网页的uv(一个人访问一个网站多次。但是还是算作一个人)
0.81%错误率!
PFadd # 创建一组元素
PFCOUNT # 统计元素的基数数量
PFMERGE # 合并两组 并集
如果不运行出错,那么使用set或者自己的数据类型即可
Bitmaps
位储存
统计用户信息,活跃,不活跃!登录、未登录!打卡! 两个状态的都可以使用Bitmaps
事务
Redis事务的本质:一组命令的集合!一个事务中的所有命令都会被序列化,再事务执行的过程中,会按照顺序执行!
Redis单条命令是保证原子性的,但是事务不保证原子性!
redis事务没有隔离级别的概念
redis事务
- 开启事务(multi)
- 命令入队(……)
- 执行事务(exec)
Redis监视(乐观锁)
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> DECRBY money 20
QUEUED
127.0.0.1:6379(TX)> INCRBY out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20
理解:watch监听状态下,开启事务,若中途有一个新的线程修改了监听的值,执行事务时失败。unwatch取消监听后,重新watch
通过Jedis操作redis
// maven导包
public static void main(String[] args ) {
// 1、new Jedis对象
Jedis jedis = new Jedis("127.0.01",6379);
// 可以使用我们之前的命令实现
System.out.pringIn(jedis.ping());
}