Redis学习笔记

Redis学习笔记

安装

wget http://download.redis.io/releases/redis-4.0.9.tar.gznode

tar -xvf redis-4.0.9.tar.gzredis

make && make install数据库

./utils/install_server.sh 配置启动浏览器

ps -ef|grep redis 查看是否启动缓存

service redis_6379 start 启动服务器

service redis_6379 stop 中止cookie

redis默认只能localhost登陆,因此须要开启远程登陆。解决方法以下:session

在redis的配置文件redis.conf中,找到bind 120.0.0.1注释掉。数据结构

protected-mode yes 改成 protected-mode noapp

redis-server 服务端命令

redis-cli 客户端命令

建立多个

复制/etc/redis/redis.conf  /etc/redis/redis6379.conf

修改pidfile与port修改成新的端口号配置:

port  7000                                        //端口7000,7002,7003        
bind 本机ip                                       //默认ip为127.0.0.1 须要改成其余节点机器可访问的ip 不然建立集群时没法访问对应的端口,没法建立集群
daemonize    yes                               //redis后台运行
pidfile  /var/run/redis_7000.pid          //pidfile文件对应7000,7001,7002
cluster-enabled  yes                           //开启集群  把注释#去掉
cluster-config-file  nodes_7000.conf   //集群的配置  配置文件首次启动自动生成 7000,7001,7002
cluster-node-timeout  15000                //请求超时  默认15秒,可自行设置
appendonly  yes                           //aof日志开启  有须要就开启,它会每次写操做都记录一条日志 

redis-server /etc/redis/redis.conf 启动便可

redis-server /etc/redis/redis.conf  & 后台启动

GUI https://redisdesktop.com/download

简介

Redis是一个远程内存数据库。提供了5种不一样类型的数据结构,经过复制、持久化和客户端分片等特性,能够方便进行扩展。

Redis是一个速度很是快的非关系型数据库,能够存储键与5种不一样类型的值之间的映射,能够将存储在内存的键值对数据持久化到硬盘,可使用复制特性来扩展读性能,可使用客户端分片来扩展写性能。

Redis与Memcached比较,性能相差无几,但Redis能够自动以两种不一样的方式将数据写入硬盘,而且能存储5种数据结构。

对于内存数据库来说,最重要的就是关机时,数据将何去何从。Reids拥有两种不一样形式的持久化方式,能够用小而紧凑的格式写入硬盘。

第一种持久化方式为时间点转储,便可以在指定时间段内有指定数量的写操做执行条件被知足时执行,还能够经过调用两条转储到硬盘命令中的任何一条来执行。

第二种持久化的方式将全部修改了数据库的命令都写入一个只追加文件里面,用户能够根据数据的重要程度,将只追加写入设置为从不一样步,每秒同步或写入一个命令就同步。

Redis实现了主从复制特性,执行复制的从服务器会链接上主服务器,接受主服务器发送的整个数据库的初始副本,以后主服务器执行的写命令,都会被发送给全部链接着的从服务器取执行,从而实时地更新从服务器的数据集。

使用Redis的理由

1. Redis的LIST和Set能够容许用户直接添加或删除元素

2. 可让代码更简单易懂、更容易维护,还可使代码的运行速度更快。

3. 能够直接使用原子的INCR命令请求并不须要通过查询分析器和查询优化器进行处理,对数据执行写的速度很是迅速。

数据结构介绍

Reids能够存储多种不一样数据类型之间的映射,分别为String(字符串)、List(列表)、Set(集合)、HASH(散列)、ZSet(有序集合)、bitmaps、hyperloglogs、地理空间(geospatial)索引半径查询。

Redis内置了复制(replication)、LUA脚本(Lua scripting)、LRU驱动事件(LRU eviction)、事务(transactions)、磁盘持久化

经过Redis哨兵(Sentinel)、自动分区(Cluster)能够提升可用性

有一部分命令是通用的,可是也有一部分命令只能对特定的一种或两种结构使用。

STRING

能够是字符串、整数、浮点型

能够对整个字符串或其中一部分进行操做,对整数和浮点数进行自增、自减

LIST

一个链表,每一个节点都包含了字符串

能够从两端推入或者弹出元素,根据偏移量进行修剪。读取单个或多个元素,查找或移除元素

SET

包含字符串的无序收集器,被包含的每一个字符串都是不一样的

能够添加、获取、移除、检查、计算交集、并集、差集、随机获取元素

HASH

包含键值对的无序散列表

能够添加、获取、移除、获取全部

ZSET

字符串成员与浮点数分值之间的有序映射,元素的排列顺序由分值大小决定

能够添加、获取、删除、筛选

Reids中的字符串

字符串命令:GET、SET、DEL

使用redis-cli,启动客户端

set hello world

get hello

del hello

Reids中的列表

一个列表结构能够有序地存储多个字符串。

LPUSH命令和RPUSH命令 将元素推入列表的左端和右端

LPOP命令和RPOP命令 从列表的左端和右端弹出元素。

LINDEX 获取列表在给定位置上的一个元素

LRANGE 获取列表在给定范围上的全部元素

127.0.0.1:6379> rpush list-key item
(integer) 1
127.0.0.1:6379> rpush list-key item2
(integer) 2
127.0.0.1:6379> rpush list-key item3
(integer) 3
127.0.0.1:6379> lrange list-key 0 -1
1) "item"
2) "item2"
3) "item3"
127.0.0.1:6379> lindex list-key 1
"item2"
127.0.0.1:6379> lpop list-key
"item"
127.0.0.1:6379> lrange list-key 0 -1
1) "item2"
2) "item3"

Redis中的集合 

Redis的集合和列表均可以存储多个字符串,列表能够存储多个相同字符串,集合使用散列表来保证本身存储的每一个字符串都是各不相同的。

集合使用无序方式存储元素,从集合的某一端弹出元素。

SADD 将元素添加到集合

SREM 从集合移除元素

SISMEMBER 快速地检查一个元素是否已经存在与集合中

SMEMBERS 获取集合包含的全部元素

127.0.0.1:6379> sadd set-key item
(integer) 1
127.0.0.1:6379> sadd set-key item2
(integer) 1
127.0.0.1:6379> sadd set-key item
(integer) 0
127.0.0.1:6379> smembers set-key
1) "item"
2) "item2"
127.0.0.1:6379> sismember set-key item3
(integer) 0
127.0.0.1:6379> sismember set-key item
(integer) 1
127.0.0.1:6379> srem set-key item
(integer) 1
127.0.0.1:6379> srem set-key item
(integer) 0
127.0.0.1:6379> smembers set-key
1) "item2"

Reids中的散列 

Reids的散列能够存储多个键值对之间的映射。和字符串不同,散列存储的值既能够时字符串又能够是数字之,一样能够自增自减。

HSET 散列关联起给定的键值对

HGET 获取指定散列键的值

HGETALL 获取散列包含的全部键值对

HDEL 若是给定键存在与散列,那么移除

127.0.0.1:6379> hset hash-key sub-key1 value1
(integer) 1
127.0.0.1:6379> hset hash-key sub-key2 value2
(integer) 1
127.0.0.1:6379> hset hash-key sub-key1 value1
(integer) 0
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "value1"
3) "sub-key2"
4) "value2"
127.0.0.1:6379> hdel hash-key sub-key2
(integer) 1
127.0.0.1:6379> hdel hash-key sub-key2
(integer) 0
127.0.0.1:6379> hget hash-key sub-key1
"value1"
127.0.0.1:6379> hgetall hash-key
1) "sub-key1"
2) "value1"

Redis中的有序集合 

有序集合和散列同样,都用于存储键值对。有序集合的键被称为成员,成员各不相同。值被称为分值,分值必须为浮点数

ZADD 将一个带有给定分值的成员添加到有序集合里面

ZRANGE 根据元素在有序排列中所处的位置,获取多个元素

ZRANGEBYSCORE 获取有序集合在给定分值范围内的全部元素

ZREM 若是给定成员存在于有序集合,那么移除成员

127.0.0.1:6379> zadd zset-key 728 member1
(integer) 1
127.0.0.1:6379> zadd zset-key 982 member0
(integer) 1
127.0.0.1:6379> zadd zset-key 1 member0
(integer) 0
127.0.0.1:6379> zrange zset-key 0 -1 withscores
1) "member0"
2) "1"
3) "member1"
4) "728"
127.0.0.1:6379> ZRANGEBYSCORE zset-key 0 1 withscores
1) "member0"
2) "1"
127.0.0.1:6379> zrem zset-key member1
(integer) 1
127.0.0.1:6379> ZREM zset-key member1
(integer) 0

ZINCRBY 用于对有序集合成员的分值执行自增操做。ZINCRBY zset-k 1 mem

HINCRBY   用于对散列存储的值执行自增操做。

EXPIRE 为这个集合设置过时时间

登录和Cookie缓存

当咱们登录互联网服务的时候,服务都会使用Cookie来记录咱们的身份,由少许数据组成,会要求咱们浏览器存储这个数据,并在每次服务发送请求时将这些数据回传给服务。

对于用来登录的cookie来讲,有两种常见的方法

一种是签名cookie,一种是令牌cookie(token)

签名cookie:一般会存储用户名、用户ID、用户最后一次登录时间,以及任何有用的信息,签名cookie还包含一个签名,服务器能够验证这个签名来验证浏览器发送的信息是否未经改动

令牌cookie:会在cookie里面存储一串随机字节做为令牌,服务器能够根据令牌在数据库查找令牌拥有着。时间的推移,旧令牌会被替换。

针对令牌Cookie的状况,可使用Redis散列来进行存储令牌和已登录用户之间的映射。要检查一个用户是否已经登录,根据令牌找对应用户,登陆状态下返回用户ID

def check_token(conn, token):
return conn.hget('login:', token)

检查令牌并不困难,复杂的工做都是在更新令牌时完成的。用户每次浏览页面,都会存储在登录散列里面的信息进行更新,并将用户的令牌和当前时间戳添加到记录最近登录用户的有序集合里面,并在被记录商品的数量超过25个时,对这个有序集合进行修剪。

def update_token(conn, token, user, item=None):
    timestamp = time.time()
    conn.hset('login:', token, user)
    conn.zadd('recent:', token, timestamp)
    if item:
        conn.zadd('viewed:' + token, item, timestamp)
        conn.zremrangebyrank('viewed:' + token, 0, -26)

经过update_token函数,每秒至少能够记录20000件商品。比关系型数据库,性能提高了10~100倍

购物车

使用cookie实现购物车,将整个购物车都存储到cookie中的作法很是常见,这种作法的一大优势是无须对数据库进行写入就能够实现购物车功能,缺点是程序须要从新解析和验证cookie,确保cookie格式正确,还有体积比较大,请求和处理的速度可能会下降

每一个用户的购物车都是一个散列,存储了商品ID与商品订购数量之间的映射。在商品数量变化时,对购物车进行更新。若是某件商品的数量大于0,添加商品ID及数量到散列里面。相反若是小于0,则移除此商品ID

def add_to_cart(conn, session, item, count):
    if count <= 0:
        conn.hdel('cart:' + session, item)
    else:
        conn.hset('cart' + session, item, count)

页面缓存 

若是页面的内容改变次数不多,能够在请求以前或以后添加层(layer)的能力,这种层一般被称为中间层、插件。能够调用Redis缓存函数,对于一个不能被缓存的请求,函数将直接生成并返回页面。对于能够被缓存的请求,函数会首先尝试从缓存里面取出并返回被缓存的页面,若是缓存页面不存在,那么会将其缓存Redis里面5分钟,最后将页面返回给调用者。

这样可让网站在5分钟以内无需为它们动态生成视图页面。

数据行缓存

对于没法被整个缓存起来的页面来说,能够经过缓存页面载入时所需的数据库行来减小载入页面所需的时间。

编写一个持续运行的守护进程函数,让函数将指定的数据行缓存到Redis里面,并不按期地对这些缓存进行更新。缓存函数会将数据行编码为JSON字典并存储在Redis字符串里面,其中数据列的名字会被映射为JSON字典的键,数据行的值则被映射为JSON字典的值。

程序使用两个有序集合来记录应该在什么时候对缓存进行更新,第一个有序集合为调度有序集合,成员为数据行的行ID,而分值则是一个时间戳,记录了什么时候将指定的数据行缓存到Redis里面。第二个有序集合为延时有序集合,成员也是数据行的行ID,分值则记录了指定数据行的缓存须要每一个多少秒进行更新。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

$

相关文章
相关标签/搜索