redis在php中使用的笔记
redis没有表的概念
由于没有数据表的概念、我们很多基于关系型数据库的查询方式、在Redis服务器上就要有新的思路。 譬如说我们通过4张表来维护用户数据、在redis上就应该只使用一个Hash 另外类似于Comment这样的表,我们就需要设计成Redis List类型 以COMMET_USERID来作为key 每一次添加一条反序列化数据进去。但这样做面临的问题是我们无法使用关系型表的其他诸如合并查询、反向查询等查询功能。
redis服务密码验证访问
配置文件中配置 requirepass yourpassword
数据库层级的访问控制
目前没有方案 考虑中 这个部分也和java服务端的朋友讨论过,Redis确实没有这方面的支持,如果考虑同一个redis服务器中有多个或者大量Saas需求、那么比较好的方式就是在最前面加一个appid的索引。
探索一下几种实现方式:
# 以saasID作为key userid做其中一项的方式
hset TRFUnmsZ userid qFVqmqMz nickname sprite
hset gdYuSu4G userid hGE5REy2 nickname amber
# 以userid作为key saasid作为其中一项
hset qFVqmqMz saasid TRFUnmsZ nickname sprite
hset Lh8PCIVy saasid TRFUnmsZ nickname soki
hset gdYuSu4G saasid hGE5REy2 nickname amber
# 以saasid拼接 keyid的方式
hset TRFUnmsZ_qFVqmqMz nickname sprite
hset TRFUnmsZ_Lh8PCIVy nickname soki
hset hGE5REy2_gdYuSu4G nickname amber
hset TRFUnmsZ_SETTING WECHATID 123456
hset TRFUnmsZ_SETTING APPNAME AppSite
hset hGE5REy2_SETTING WECHATID 654321
基于Redis只能通过key进行查询、不能使用类似于MySQL的WHERE查询,所以用saasid作为key的方式被摒弃。我们不可能取出所有的saas下的数据 再到程序里查找。
第二个方案以userid作为key 追加 saasid字段,可取。 首先基于我采用的是8位区分大小写字符串来生成随机ID,天然就很适合进行hash存取。同时也几乎不会有重复的可能性。我们简单做一下计算 62的7次方 52 (首位不用数字) 至少是 1.8 10的14次方 基本不用考虑重复的情况。 即使我们有重复、可以通过saasid来进行校验
这个方案的问题在于 非Hash索引的数据,比如说系统设置。 这种我们通常会用一些关键字来定义key ,如 APP_NAME,WECHAT_ID等 这时有多少个saas用户 就会有多少个重复。无法进行有效存取了。
那么第三个方案字符串拼接。 在第三个方案的时候,其实我们并不应该使用HASH 因为相对来说SETTING的动态存取概率不大,另外总数据量也相对很小。应该直接使用SET来进行存取。 而且应该将所有的设置(可以按分类) 进行反序列化之后存到REDIS. 使用的时候只需要一次序列化开销即可。 不过并不saasid作为前缀的方案,这里事实上可以优化一下saasid的位数,我们使用4位ID 既可以支持1400万的saas用户,5位ID支持7亿。 由于saasid并不会是一个高并发的事件,所以我们可以做到每一次生成之前都做一次全表查询,完全不必担心冲突时候产生的副作用。
当然,图省事儿的话直接8位ID问题不大。
# 优化后的 用户存储
hset TRFU_qFVqmqMz nickname sprite
hset TRFU_Lh8PCIVy nickname soki
hset hGE5_gdYuSu4G nickname amber
# 优化后的 设置存储
set TRFU_SETTING {\"WECHATID\":\"123456\",\"APPNAME\":\"AppSite\"}
仅作为高速数据库缓存时的用法
上面有很多用法的探索,但是如果我们仅仅考虑做一个缓存的时候。我们很多工作和思路可以简化或通用。我们可以将全部的数据采用通用的存取方式,然后将它存储到一个经过唯一HASH的key中去。 这和我在AppSiteJS前端缓存中的做法是相同的,区别在于js中存储数据到localStorage中而且localstorage数据量增大之后,查询效率明显下降,所以需要做好数据量的控制。
在服务端进行数据缓存还需要注意,由于数据是可变的,需要在数据产生变化的时候同步更新到缓存中,亦或是在数据库的数据产生更新时删除缓存。这两个方案各有优劣,查询频率高的应当同步更新,而更新频率高的应当直接删除缓存。 当然从大概率来说,还是前者更多,所以主要考虑同步更新。
文章地址: redis在php中使用的笔记 - Sprite keep learning
最近回复