Python全栈(六)项目前导之2.Redis数据类型和Python操作Redis

一、Redis-Hash类型

hash是一个键值对集合。
hash是一个string类型的field和value的映射表,hash特别适合存储对象

1.hset/hget/hmset/hmget/hgetall/hdel

意义分别是:
设值/取值/设值多个值/取多个值/取全部值/删除值
测试如下:

127.0.0.1:6379> keys *
 1) "l3"
 2) "name"
 3) "age"
 4) "data"
 5) "l4"
 6) "proxies"
 7) "first"
 8) "l1"
 9) "l2"
10) "num"
127.0.0.1:6379> hset user id 1
(integer) 1
127.0.0.1:6379> hget user id
"1"
127.0.0.1:6379> hset user name corley
(integer) 1
127.0.0.1:6379> hget user name
"corley"
127.0.0.1:6379> hset user id 2
(integer) 0
127.0.0.1:6379> hget user id
"2"
127.0.0.1:6379> hgetall user
1) "id"
2) "2"
3) "name"
4) "corley"
127.0.0.1:6379> hmset users id 1 name corley sex 1
OK
127.0.0.1:6379> hmget users id name sex
1) "1"
2) "corley"
3) "1"
127.0.0.1:6379> hgetall users
1) "id"
2) "1"
3) "name"
4) "corley"
5) "sex"
6) "1"
127.0.0.1:6379> hdel user id
(integer) 1
127.0.0.1:6379> hgetall user
1) "name"
2) "corley"
127.0.0.1:6379> hdel user name
(integer) 1
127.0.0.1:6379> hgetall user
(empty list or set)

get *会发现之前的值都还在,这是Redis使用持久化技术将数据保存到了本地磁盘,查看Redis目录,可以看到有一个文件dump.rdb,就是用于保存数据的。
键可以重复,重复时会覆盖,但是在使用时应该尽量避免使用重复的键。

2.hlen

求哈希长度。
测试如下:

127.0.0.1:6379> type users
hash  
127.0.0.1:6379> hlen users
(integer) 3                                   

3.hexists key

判断在key里面的某个值是否存在,存在返回1 ,不存在返回0。
测试如下:

127.0.0.1:6379> hexists users id
(integer) 1
127.0.0.1:6379> hexists users height
(integer) 0

4.hkeys/hvals

列举出所有的key和value。
测试如下:

127.0.0.1:6379> hkeys users          
1) "id"                              
2) "name"                            
3) "sex"                             
127.0.0.1:6379> hvals users          
1) "1"                               
2) "corley"                          
3) "1"                               

二、Redis-Set类型

set是string类型的无序集合。
Set中不存在不重复的值,和普通的集合一样。

1.sadd/smembers/sismember

表示添加/查看集合/查看是否存在
举例:

sadd set01 1 2 2 3 3 去掉重复添加
smembers set01 得到set01的所有元素
sismember set01 1 如果存在返回1,不存在返回0

扫描二维码关注公众号,回复: 10190937 查看本文章

测试如下:

127.0.0.1:6379> sadd se 1 2 2 3 3 4
(integer) 4
127.0.0.1:6379> smembers se
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sismember se 2
(integer) 1
127.0.0.1:6379> sismember se 5
(integer) 0

2.scard

获取集合里面的元素个数。
测试如下:

127.0.0.1:6379> scard se
(integer) 4

3.srem key value

删除集合中元素。
测试如下:

127.0.0.1:6379> srem se 3
(integer) 1
127.0.0.1:6379> smembers se
1) "1"
2) "2"
3) "4"
127.0.0.1:6379> srem se 5
(integer) 0

4.srandmember key

随机返回数。
测试如下:

127.0.0.1:6379> srandmember se
"1"                           
127.0.0.1:6379> srandmember se
"2"                           
127.0.0.1:6379> srandmember se
"4"                           
127.0.0.1:6379> srandmember se
"2"                           
127.0.0.1:6379> srandmember se
"2"                           
127.0.0.1:6379> srandmember se
"1"                           
127.0.0.1:6379> smembers se   
1) "1"                        
2) "2"                        
3) "4"                        

5.spop key

随机弹出元素。
测试如下:

127.0.0.1:6379> spop se
"2"
127.0.0.1:6379> spop se
"4"
127.0.0.1:6379> spop se
"1"
127.0.0.1:6379> sadd se1 1 7 5 3 2 4 7
(integer) 6
127.0.0.1:6379> spop se1
"7"
127.0.0.1:6379> spop se1
"3"
127.0.0.1:6379> spop se1
"2"
127.0.0.1:6379> smembers se1
1) "1"
2) "4"
3) "5"

6.smove key1 key2

移动元素。
举例说明:

smove set01 set03 2 将set01中的2 移动到set03中

测试如下:

127.0.0.1:6379> smove se1 se 1
(integer) 1
127.0.0.1:6379> smembers se
1) "1"

7.集合操作

与数学中的集合操作类似,其中:

  • SDIFF
    差集操作
  • SINTER
    交集操作
  • SUNION
    并集操作

测试如下:

127.0.0.1:6379> sadd set01 1 2 3 4 5
(integer) 5                         
127.0.0.1:6379> sadd set02 1 2 3 a b
(integer) 5                         
127.0.0.1:6379> SDIFF set01 set02   
1) "4"                              
2) "5"                              
127.0.0.1:6379> SINTER set01 set02  
1) "1"                              
2) "2"                              
3) "3"                              
127.0.0.1:6379> SUNION set01 set02  
1) "4"                              
2) "a"                              
3) "1"                              
4) "2"                              
5) "3"                              
6) "5"                              
7) "b"                              

三、Redis-Zset类型

ZSet是Redis中的有序集合类型。

1.zadd/zrange

设置和根据范围获取值。
测试如下:

127.0.0.1:6379> zadd ze 60 v1 70 v2 80 v3 90 v4 100 v5
(integer) 5
127.0.0.1:6379> zrange ze 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
127.0.0.1:6379> zadd ze1 60 v1 70 v2 80 v3 100 v4 90 v5
(integer) 5
127.0.0.1:6379> zrange ze1 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v5"
5) "v4"
127.0.0.1:6379> zadd ze2 60 v1 70 v2 80 v3 90 v4 90 v5
(integer) 5
127.0.0.1:6379> zrange ze2 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
127.0.0.1:6379> zadd ze3 name v1 age v2 80 v3 90 v4 90 v5
(error) ERR value is not a valid float
127.0.0.1:6379> zadd ze4 60 v1 70 v2 80 v1 90 v4 90 v5
(integer) 4
127.0.0.1:6379> zrange ze4 0 -1 withscores
1) "v2"
2) "70"
3) "v1"
4) "80"
5) "v4"
6) "90"
7) "v5"
8) "90"

显然,zset的值只能是数值型(浮点数),如果是字符串会报错;
如果键相同,后边对应的值会覆盖前面对应的值。

2.zrangebyscore key start end

根据开始结束来取值;
结束不包括用 (
limit限制从指定索引开始获取指定条数据。
测试如下:

127.0.0.1:6379> zrangebyscore ze 60 80
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> zrangebyscore ze 60 (80
1) "v1"
2) "v2"
127.0.0.1:6379> zrangebyscore ze 60 80 limit 1 2
1) "v2"
2) "v3"
127.0.0.1:6379> zrangebyscore ze 60 80 limit 1 2
1) "v2"
2) "v3"
127.0.0.1:6379> zrangebyscore ze 60 80 limit 0 2
1) "v1"
2) "v2"

3.zrem key

删除元素。
测试如下:

127.0.0.1:6379> zrem ze v1
(integer) 1
127.0.0.1:6379> zrange ze 0 -1
1) "v2"
2) "v3"
3) "v4"
4) "v5"

4.zcard/zcount/zrank

获取数据总数/指定范围的数据个数/返回数据对应下标
测试如下:

127.0.0.1:6379> zcard ze
(integer) 4
127.0.0.1:6379> zcount ze 70 90
(integer) 3
127.0.0.1:6379> zrank ze v4
(integer) 2

四、Python操作Redis

1.Python中redis的安装和连接

如果未安装redis库,需要先通过命令安装:

pip install redis

连接方式如下 :

r = redis.StrictRedis(host='localhost',port=6379,db=0)

2.Python操作Redis-String

简单测试:

import redis

r = redis.StrictRedis(host='localhost', port=6379, db=0)  # 与redis.Redis()效果相同

print(r)

打印

Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>

显然,r是一个redis对象。

封装类操作:

import redis


class StringRedis(object):
    def __init__(self):
        self.r = redis.StrictRedis()  # 因连接参数为默认,所以可以不带参数

    def string_set(self, key, item):
        '''字符串设置值'''
        res = self.r.set(key, item)  # 返回布尔值
        print(res)

    def string_get(self, key):
        '''字符串取值'''
        res = self.r.get(key) # 返回字节型数据
        return res


if __name__ == '__main__':
    s = StringRedis()
    s.string_set('user', 'corley')
    res = s.string_get('user')
    print(type(res), res)

打印

True
<class 'bytes'> b'corley'

进一步完善操作:

import redis


class StringRedis(object):
    def __init__(self):
        self.r = redis.StrictRedis()  # 因连接参数为默认,所以可以不带参数

    def string_set(self, key, item):
        '''字符串设置值'''
        res = self.r.set(key, item)  # 返回布尔值
        print(res)

    def string_get(self, key):
        '''字符串取值'''
        res = self.r.get(key) # 返回字节型数据
        return res

    def string_mset(self, items):
        '''字符串设置多个值'''
        if isinstance(items, dict):
            res = self.r.mset(items) # 返回布尔值
            print(res)

    def string_mget(self, keys):
        '''字符串取多个值'''
        if isinstance(keys, list):
            return self.r.mget(keys)

    def string_del(self, key):
        '''删除值'''
        if self.r.exists(key):
            self.r.delete(key)
        else:
            return '%s Not Found' % key

if __name__ == '__main__':
    s = StringRedis()
    s.string_set('user', 'corley')
    res1 = s.string_get('user')
    print(type(res1), res1)
    d = {
        'age':18,
        'sex':1
    }
    s.string_mset(d)
    res2 = s.string_mget(['user', 'age', 'sex'])
    print(type(res2), res2)
    res3 = s.string_del('user')
    res4 = s.string_del('name')
    print(res3, res4)

打印

True
<class 'bytes'> b'corley'
True
<class 'list'> [b'corley', b'18', b'1']
None name Not Found

3.Python操作Redis-List

import redis


class ListRedis(object):
    def __init__(self):
        self.r = redis.StrictRedis()

    def list_lpush(self, key, item):
        '''列表设置值'''
        res = self.r.lpush(key, item)  # 返回布尔值
        print(res)

    def list_lpop(self, list):
        '''列表弹出值'''
        res = self.r.lpop(list) # 返回字节型数据
        return res


if __name__ == '__main__':
    l = ListRedis()
    l.list_lpush('li', 1)
    l.list_lpop('li')

打印

1

Python中List添加值一次只能添加一个,如有多个,可以使用循环。
再次测试:

import redis


class ListRedis(object):
    def __init__(self):
        self.r = redis.StrictRedis()

    def test_push(self):
        res = self.r.lpush('test','1')
        res = self.r.rpush('test','2')
        res = self.r.rpush('test','3')

    def test_pop(self):
        res = self.r.lpop('test')
        print(res)
        res = self.r.rpop('test')
        print(res)

    def test_range(self):
        res = self.r.lrange('test',0,-1)
        print(res)


if __name__ == '__main__':
    l = ListRedis()
    l.test_push()
    l.test_range()
    l.test_pop()

打印

[b'1', b'2', b'3']
b'1'
b'3'

4.Python操作Redis-Set

简单操作示例如下:

import redis


class SetRedis(object):
    def __init__(self):
        self.r = redis.StrictRedis()

    def test_sadd(self):
        res = self.r.sadd('set1','1','2')

    def test_del(self):
        res = self.r.srem('set1',1)

    def test_pop(self):
        res = self.r.spop('set1')

    def test_members(self, key):
        res = self.r.smembers(key)
        print(res)


if __name__ == '__main__':
    s = SetRedis()
    s.test_sadd()
    s.test_members('set1')
    s.test_del()
    s.test_members('set1')
    s.test_pop()
    s.test_members('set1')

打印

{b'2', b'1'}
{b'2'}
set()

5.Python操作Redis-Hash

用Python操作Redis-Hash示例如下:

import redis


class HashRedis(object):
    def __init__(self):
        self.r = redis.StrictRedis()

    def test_hset(self):
        dic = {
            'id': 1,
            'name': 'huawei'
        }
        res = self.r.hmset('mobile', dic)

    def test_hgetall(self):
        res = self.r.hgetall('mobile')
        print(res)

    def test_hexists(self):
        res = self.r.hexists('mobile', 'id')
        print(res)


if __name__ == '__main__':
    h = HashRedis()
    h.test_hset()
    h.test_hgetall()
    h.test_hexists()

打印

{b'id': b'1', b'name': b'huawei'}
True

五、Redis主从配置

1.主从概念

在实际过程中,缓存可能因为内存占用更多或其他不可预料的因素而崩溃,这样会使得用户直接访问数据库,从而导致主数据据库的访问压力大大增加,所以为了使缓存不易发生数据库崩溃,应该对缓存建立主从配置,从而提高系统的容灾性能。
缓存的主从配置
Redis主从配置特性如下:

  • ⼀个master可以拥有多个slave,⼀个slave⼜可以拥有多个slave,如此下去,形成了强⼤的多级服务器集群架构
  • master用来写数据,slave用来读数据,读数据比写数据多得多(据统计,网站的读写比率是10:1)
  • 通过主从配置可以实现读写分离
  • master和slave都是一个redis实例(redis服务)

示意如下:
master-slave

2.主从配置过程

以下相关操作均是在Linux(Kali)进行的。
可以在Redis配置文件中设置守护线程参数daemonize为yes,以便后面更方便地开启Redis服务,如下:
daemonize yes

配置主机和开启服务

  • 修改redis.conf配置文件

bind 0.0.0.0 # 或者改成本机IP

  • 开启主机服务
src/redis-server redis.conf

配置从机和开启服务

  • 复制redis.conf配置文件
cp redis.conf slave.conf
  • 修改slave.conf文件
    有3处修改的地方:

bind 192.168.186.132(主机IP,通过ifconfig名获取)

port 6378(从机端口)

replicaof 192. 168.186.132(主机IP) 6379(主机端口) # 旧版本Redis中为slaveof

在配置文件中位置示意如下:
bind
port
replicaof

  • 开启从机服务
src/redis-server slave.conf

主从数据操作测试

  • 连接主从客户端
src/redis-cli -p 6379
src/redis-cli -h 192.168.186.132 -p 6378
  • 读写数据
    在主机上写数据:
set name corley

在从机上读数据:

get name

具体演示过程如下:
redis master-slave config test
可以看出,主机才有写权限,从机只能读

发布了93 篇原创文章 · 获赞 739 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/CUFEECR/article/details/105115289