使用Redis构建支持程序
在Linux和Unix世界中,有两种常见的记录日志的方法。第一种是将日志记录到文件里面,然后随着时间流逝不断地将一个有一个日志行添加到文件里面,并在一段时间之后创建新的日志文件。包括Redis在内的很多软件都是用这种方法来记录日志。当这种记录日志的方式可能会有个问题,因为每个不同的服务都会创建不同的日志,而这些日志轮换日志的机制也各不相同,并且缺少一种能够方便得聚合所有日志并对其进行处理的常用方法。syslog服务是第二种常用的日志记录方法,这个服务运行在几乎所有Linux服务器和Unix服务器的514号TCP端口和UDP端口上面。syslog接受其他程序发来的日志消息,并将这些消息路由至存储在硬盘上的各个日志文件里面。syslog还负责旧日志的轮换和删除工作。通过配置,syslog甚至可以将日志消息转发给其他服务来做进一步的处理。因为对指定的日志的轮换和删除工作都可以交给syslog来完成,所以使用syslog服务比直接将日志写入文件要方便的多。syslog的转发功能可以将不同的日志分别存储到同一台服务器的多个文件里面。
对计数器进行更新
使用给一个散列来存储网站在每个5秒时间片之内获得的点击量。其中散列的每个键都是某个时间片的开始时间,而键对应的值则存储了网站在该时间片之内获得的点击量。为了能够清理计数器包含的旧数据,我们需要在使用计数器的同时,对被使用的计数器进行记录。我们需要一个有序序列。这个序列不能包含任何重复的元素,以方便能遍历序列中的所有元素。实现有序序列的最好的办法是是有有序集合,有序集合的各个成员分别由计数器的精度以及计数器的名字组成,而所有成员的分值都为0。当所有成员的分值都被设置成了0,所有Redis在尝试按分值对有序程序集合进行排序时,就会使用各成员名进行排序。对于每种时间片精度,程序都会将计数器的精度和名字作为引用信息添加到记录已有计数器的有序集合里面,并增加散列计数器在指定时间片内的计数值。更新计数器只需要为每种时间片精度执行ZDD命令和HINCRBY名。从指定精度和名字的计数器里面获取数据只需要使用HGETALL命令来获取整个散列,接着将命令返回的时间片和计数器的值从原来的字符串格式转换成数字格式,根据时间对数进行排序,最后返回排序后的数据。在处理和清理旧计数器时,需要留心一下几点:任何时候都可能会有新的计数器被添加进来;同一时间可能会有多个不同的清理操作在执行;对于一个每天只更新一次的计数器来说,以每分钟一次的频率尝试清理这个计数器只会浪费计算机资源;若一个计数器不包含任何数据,那么程序就不应该对它进行清理。清理程序通过对记录已知计数器的有序集合执行ZRANGE命令来一个接一个的遍历所有已知的计数器。在对计数器执行清理操作时,程序会取出计数器记录的所有技术样本的开始时间,并移除那些开始时间位于指定截止时间之前的样本,清理之后的计数器最多只会保留最新的120个样本。若一个计数器在执行清理操作之后不再包含任何样本,那么程序将从记录已知计数器的有序集合里面移除这个计数器的引用信息。程序在每次遍历有序集合里面记录的计数器时都会对计数器进行检查,确保只清理应该清理的计数器。当程序尝试清理一个计数器的时候,它会取出计数器技术的所有数据样本,并判断哪些样本是需要被删除的。若程序在对一个计数器执行清理操作之后,认为这个计数器已经不再包含任何数据,那么程序会检查这个计数器是否已经被清空,并在确认了它已经被清空之后,将它从记录已知计数器的有序集合中移除。最后,在遍历完计数器之后,程序会计算此次遍历消耗的时长,若没有达到一分钟,则程序将休眠知道这分钟过去,然后继续下次清理。
使用Redis存储统计数据
对于给定上下文和类型,程序将使用一个有序集合来记录这个上下文以及这个类型的最小值,最大值,样本数量值的和,值得平方值和等信息,并通过这些信息来计算平均值以及标准差。程序将值存储在有序集合是为了统计信息的有序集合和其他有序集合进行并集计算,并通过MIN和MAX这两个聚合函数来筛选相交的元素。统计程序在写入数据之前会进行检查,确保被记录的是当前这一个小时的统计数据,并将不属于当前这个小时的旧数据进行归档。再辞职后,程序会构建两个临时有序集合,其中一个用于用于保存最小值,而另一个则用于保存最大值。然后使用ZUNIONSTORE命令以及它的两个聚合函数MIN和MAX,分别计算两个临时有序集合与记录当前统计数据的有序集合之间的并集结果。通过使用ZUNIONSTORE命令,程序可以快速地更新统计数据而无需使用WATCH去监视可能会频繁地进行更新存储统计数据的键。程序在并集计算完毕之后会删除临时有序集合,并使用ZINCRBY命令对统计数据有序集合里面的count,sum,sumsq更新。
查找IP所属城市以及国家
实现IP所属地查找程序需要用到两个查找表,第一个查找表需要根据输入的IP地址来查找IP所属城市的ID,而第二个查找表则需要根据输入的城市ID来查找ID对应城市的真实信息。根绝IP地址来查找城市ID的查找表由有序集合实现。这个有序集合的成员为具体的城市ID,分值这则是根据IP地址计算出的整数值。要根据给定IP查找所属城,先要将IP地址转换成分值,然后在所有分值小于或等于给定IP地址的地址里面,找出分值最大的那个IP所对应的城市ID。可以通过ZREVRANGBYSCORE命令并将选项START和NUM参数分别设为0和1完成。
使用Redis存储配置信息
将配置信息存储在Redis里面,并编写应用程序来获取这些信息,就不用再编写工具来向服务器推送配置信息了,服务器和服务也不用再通过重载配置文件的方式来更新配置信息了。可以把一个已知的Redis服务器用作配置信息字典,然后通过这个字典存储的配置信息来连接为不同应用或服务组件提供数据的其他Redis服务器。构建一个函数,该函数可以从一个键里面取出一个JSON编码的配置项值,其中存储配置值的键由服务的类型以及使用该服务的引用程序命名。
定义一个可以接受指定的配置作为参数并生成一个包装器的装饰器。这个包装器可以包裹起一个函数,使得之后被包裹的函数逇调用可以自动连接至正确的Redis服务器,并且连接Redis服务器所使用的那个连接会和用户之后提供的其他参数一同被传递至包裹的函数。
使用Redis构建支持程序的更多相关文章
- redis实战笔记(5)-第5章 使用 Redis构建支持程序
本章主要内容 1.使用Redis记录日 志 2.使用Redis实现计数器并进行数据统计 3.查询IP地址所属的城市与国家 4.服务的发现与配置 这一章将介绍如何使用Redis来帮助和支持系统的其他 ...
- nginx+lua+redis构建高并发应用(转)
nginx+lua+redis构建高并发应用 ngx_lua将lua嵌入到nginx,让nginx执行lua脚本,高并发,非阻塞的处理各种请求. url请求nginx服务器,然后lua查询redis, ...
- redis实战笔记(6)-第6章 使用 Redis构建应用程序组件
本章主要内容 1.构建两个前缀匹配自 动补全程序 2.通过构建分布式锁来提高性能 3.通过开发计数信号量来控制并发 4.构建两个不同用途的任务队列 5.通过消息拉取系统来实现延迟消息传递 6.学习 ...
- redis实战笔记(2)-第2章 使用 Redis构建Web应用
第2章 使用 Redis构建Web应用 本章主要内容 1.登录cookie 2.购物车cookie 3.缓存生成的网页 4.缓存数据库行 5.分析网页访问记录 本章的所有内容都是围绕着发现并解 ...
- Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session框架
Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session import tornado.ioloop import tornado.web from myhas ...
- Redis构建全局并发锁
Redis构建全局并发锁 https://www.cnblogs.com/FG123/p/9990336.html 谈起Redis的用途,小伙伴们都会说使用它作为缓存,目前很多公司都用Redis作为缓 ...
- 《Redis官方文档》用Redis构建分布式锁
用Redis构建分布式锁 在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简 ...
- 使用redis构建分布式锁
Redis使用WATCH命令来代替对数据进行加锁,因为WATCH只会在数据被其他客户端抢先修改了的情况下通知执行了这个命令的客户端,但是不会阻止其他客户端对数据进行修改,所以这个命令被称为乐观锁. 但 ...
- Redis构建分布式锁
1.前言 为什么要构建锁呢?因为构建合适的锁可以在高并发下能够保持数据的一致性,即客户端在执行连贯的命令时上锁的数据不会被别的客户端的更改而发生错误.同时还能够保证命令执行的成功率. 看到这里你不禁要 ...
随机推荐
- php多线程代码
<?php$thNum = 20; //20个进程$total = 20000;//总数$pageNum=100;//每个页面显示100条数据 $pageCount = ceil($total/ ...
- leetcode-algorithms-15 3Sum
leetcode-algorithms-15 3Sum Given an array nums of n integers, are there elements a, b, c in nums su ...
- jq回车触发绑定点击事件
//jq绑定回车事件触发点击事件<script> $(function(){ $(document).keyup(function(event){ if(event.keyCode ==1 ...
- IntelliJ IDEA2017创建web工程并实现远程部署tomca【转载】
[IntelliJ IDEA2017创建web工程并实现远程部署tomcat] 作者:https://segmentfault.com/a/1190000012762629 将应用打成war包方式 步 ...
- mysql 数据库的CUDR
mysql删表和建表语句: DROP TABLE IF EXISTS `t_blog_user`;CREATE TABLE `t_blog_user` ( `id` int(11) NOT NULL ...
- Qt绘制文本二 弯曲排列和旋转效果 弧形路径 正弦函数路径
void WgtText::paintEvent(QPaintEvent *event) { QPainter painter(this); QString m_string("abcdef ...
- 关于datetimepicker只显示年、月、日的设置
如下是只显示月的sample code: <link rel="stylesheet" href="css/datetimepicker/bootstrap-dat ...
- linux下grep命令详解
参数: -a 或 --text : 不要忽略二进制的数据. -A<显示行数> 或 --after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行 ...
- 请问微信小程序let和var以及const有什么区别
在JavaScript中有三种声明变量的方式:var.let.const. var:声明全局变量,换句话理解就是,声明在for循环中的变量,跳出for循环同样可以使用. [JavaScript] 纯文 ...
- Win10系列:UWP界面布局基础2
属性设置 在面向对象程序开发中,所提及的属性通常指的是对象的属性.在XAML代码中,定义元素时也可以为其设置属性,例如对于一个TextBox元素,有背景属性.宽度属性和高度属性等.为了满足实际应用的需 ...